2013-04-25 148 views
1

我有一个方法获取对象的属性的值,并附加一些逗号。我想制作这个generinc,所以我可以将它与其他对象一起使用。如何循环访问c#中的对象的属性?

  foreach (var row in rows.ToList()) 
      { 
       sbResult.Append(
        delimiter + row.MediaName + delimiter + separator + 
        delimiter + row.CountryName + delimiter + separator + 
        delimiter + row.ItemOverRideDate + delimiter + separator + 
        delimiter + row.Rating + delimiter + separator + 
        delimiter + row.BatchNo + delimiter + separator + 
        delimiter + row.NoInBatch + delimiter + separator + 
        delimiter + row.BatchDate + delimiter + separator + 
        delimiter + row.DataType + delimiter + separator + 
        delimiter + row.ByLine + delimiter + separator + 
        delimiter + row.IssueNo + delimiter + separator + 
        delimiter + row.Issue + delimiter + separator + 
        delimiter + row.MessageNo + delimiter + separator + 
        delimiter + row.Message + delimiter + separator + 
        delimiter + row.SourceName + delimiter + separator + 
        delimiter + row.SourceType + delimiter + separator); 

       //end of each row 
       sbResult.AppendLine(); 
      } 

我一直在使用var rowData = row.GetType().GetProperties();尝试,但它只返回属性本身,我不知道如何获取属性的值。

+3

我建议你保存,如果你想在它们之间迭代特性的数据结构(如字典或ArrayList中)。 – Patashu 2013-04-25 12:25:10

回答

2

由于Type.GetProperties返回PropertyInfo的集合,因此请通过致电PropertyInfo.GetValue来追踪该问题。这里是你如何能做到这一点(和所有其余一起)与LINQ:

var line = string.Join(
      row.GetType().GetProperties() 
       .Select(pi => pi.GetValue(row)) 
       .Select(v => delimiter + v.ToString() + delimiter), 
      separator); 

但是,您可能要重新考虑你的方法。如果GetProperties获取静态属性或索引器以及“常规”属性,则此代码将中断;它还要求代码以完全信任的方式运行(否则不能反射)。最后,它将会是slow,因为a)反射本质上很慢,b)它会一直反复重复同样的事情,而不会缓存它已经发现的任何信息。

除了上述潜在的问题,如果您甚至有远程机会希望过滤打印出来的内容,最好将此逻辑封装在row的(virtual?)方法中,像

sbResult.AppendLine(row.SerializeAsLine()); 
0
var values = instance 
    .GetType() 
    .GetProperties(BindingFlags.Instance | BindingFlags.Public) 
    .Select(z => string.Format("{0}: {1}\n", z.Name, z.GetValue(instance, null))); 

string res = string.Concat(values); 

其中instance是您的对象的实例。如果需要StringBuilder(取决于属性的数量),您可能需要避免使用LINQ并使用循环。

0

您可以使用这样的事情来遍历特定类型的所有属性:

public static IEnumerable<KeyValuePair<string, T>> PropertiesOfType<T>(object obj) 
{ 
    return from p in obj.GetType().GetProperties() 
      where p.PropertyType == typeof(T) 
      select new KeyValuePair<string, T>(p.Name, (T)p.GetValue(obj)); 
} 

然后,你可以指定类型为string所有你的字符串属性。

可编译样品:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     private static void Main() 
     { 
      var test = new Test 
      { 
       Str1 = "S1", 
       Str2 = "S2", 
       Str3 = "S3", 
       Str4 = "S4" 
      }; 

      foreach (var property in PropertiesOfType<string>(test)) 
      { 
       Console.WriteLine(property.Key + ": " + property.Value); 
      } 
     } 

     public static IEnumerable<KeyValuePair<string, T>> PropertiesOfType<T>(object obj) 
     { 
      return from p in obj.GetType().GetProperties() 
        where p.PropertyType == typeof(T) 
        select new KeyValuePair<string, T>(p.Name, (T)p.GetValue(obj)); 
     } 
    } 

    public class Test 
    { 
     public string Str1 { get; set; } 
     public string Str2 { get; set; } 
     public string Str3 { get; set; } 
     public string Str4 { get; set; } 
    } 
} 
0

这。

List<PropertyInfo> _propInfo = _row.GetType().GetProperties(); 

    foreach (var item in _propInfo) 
    { 
    object _value = item.GetValue(_row, null); 
    if (_value != null) 
    { 
    // Save the Value 
    } 
    } 
0

GetProperties返回PropertyInfo数组,所以使用GetValue方法和使用的对象,因为它的投入,得到每个属性的值。下面是代码:

public class MyClass 
{ 
    public string MyProperty1 { get; set; } 
    public string MyProperty2 { get; set; } 
    public string MyProperty3 { get; set; } 
} 

然后

MyClass myObj = new MyClass() { MyProperty1 = "first", MyProperty2 = "second", MyProperty3 = "third" }; 

List<string> array = new List<string>(); 

foreach (var item in typeof(MyClass).GetProperties()) 
{ 
    array.Add(item.GetValue(myObj, null).ToString()); 
} 

var result = string.Join(",", array); //use your own delimiter