2014-01-22 29 views
1

.NET 4.5 C#列表和它們的值

爲了支持「導出到Excel」功能很多類,我需要能夠採取一個類,然後從它那裏得到公衆的列表屬性名稱(用於標題)和屬性值(用於行)

有沒有辦法反映一個類的實例並獲取屬性名稱和屬性值?

回答

1

下面是如何做到這一點的快速示例。當然,您需要更新它,以便正確創建/構建CSV,但這會讓您瞭解如何獲取所需的值。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var myClass = new MyClass() 
     { 
      Number = 1, 
      String = "test" 
     }; 

     var properties = myClass.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 

     foreach (var property in properties) 
     { 
      var columnName = property.Name; 
      var value = myClass.GetType().GetProperty(columnName).GetValue(myClass, null); 

      Console.WriteLine(string.Format("{0} - {1}", columnName, value)); 
     } 
     Console.ReadKey(); 
    } 
} 

public class MyClass 
{ 
    public int Number { get; set; } 
    public string String { get; set; } 
} 
0

你可以使用一些像這樣:

public static Dictionary<string, object> KeyValue(object obj) 
{ 
    return obj.GetType().GetProperties().ToDictionary(
     m => m.Name, 
     m => m.GetValue(obj, new object[] { }) 
    ); 
} 
1

其實我最近創建這樣的事情對我的工作。我正在編寫一個自定義CSV序列化程序類以支持構思不良的CSV文件規範。

public CSVSerializer Serialize<T>(T data, Func<T, object> map) 
{ 
    if (map == null) throw new ArgumentNullException("map"); 

    object mappedData = map(data); 
    if (mappedData == null) throw new NullReferenceException("Mapped data produced null value"); 

    // Iterate over public members of `mappedData` 
    MemberInfo[] members = mappedData.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public); 
    List<string> values = new List<string>(); 
    foreach (MemberInfo member in members) 
    { 
     // Skip events and methods 
     if (!(member is FieldInfo || member is PropertyInfo)) continue; 

     // Value of `mappedData` 
     object memberVal = MemberInfoValue(member, mappedData); 
     if (memberVal == null) 
     { 
      // If the actual value stored by `memberVal` is null, store string.Empty and continue 
      values.Add(string.Empty); 
      continue; 
     } 

     // Check if `memberVal` contains a member named "map" 
     MemberInfo[] maps = memberVal.GetType().GetMember("map"); 
     MemberInfo memberMap = maps.Length > 0 ? maps[0] : null; 
     string val = MapToString(memberVal, o => o.ToString()); 

     if (map != null) // map is present 
     { 
      // Get first property other than map 
      MemberInfo dataVal = memberVal.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public) 
               .Where(mi => mi is FieldInfo || mi is PropertyInfo) 
               .Except(new MemberInfo[] { memberMap }) 
               .DefaultIfEmpty(memberMap) 
               .FirstOrDefault(); 

      object tmp = MemberInfoValue(memberMap, memberVal); 
      if (dataVal == memberMap) 
      { 
       // map is only property, so serialize it 
       val = MapToString(tmp, o => o.ToString()); 
      } 
      else 
      { 
       // try to serialize map(dataVal), or use empty string if it fails 
       Delegate dlg = tmp as Delegate; 
       if (dlg != null) 
       { 
        object param = MemberInfoValue(dataVal, memberVal); 
        try { val = MapToString(dlg, d => d.DynamicInvoke(param).ToString()); } 
        catch (Exception ex) 
        { 
         // exception should only occur with parameter count/type mismatch 
         throw new SerializationException(string.Format("Poorly formatted map function in {0}", member.Name), ex); 
        } 
       } 
       else 
       { 
        // map is not a delegate (!!) 
        throw new SerializationException(string.Format("map member in {0} is not a delegate type", member.Name)); 
       } 
      } 
     } 

     // Handle quotes and the separator string 
     val = val.Trim('"'); 
     if (val.Contains("\"")) 
     { 
      val = val.Replace("\"", "\\\""); 
     } 
     if (val.Contains(Separator)) 
     { 
      val = string.Format("\"{0}\"", val); 
     } 

     values.Add(val); 
    } 
    string line = string.Join(Separator, values); 
    Writer.WriteLine(line); 

    return this; 
} 

此功能串行化他們定義的順序公共領域和data性能;這些成員的名字被忽略。

如果您只對屬性感興趣,您可以使用GetProperties而不是GetMembers(使用PropertyInfo而不是MemberInfo)。如果您沒有創建CSV,那麼您顯然可以忽略CSV文件格式部分。

MemberInfoValue(info, parent)返回((FieldInfo)info).GetValue(parent)((PropertyInfo)info).GetValue(parent, null),視情況而定。 MapToString只是一個空防護功能。

map參數的存在和尋找名爲「map」的成員是我特殊情況的必需品之一,儘管它對您有用。該映射允許的東西,如:

mySerializer.Serialize(myPersonObject, 
    p => new { 
     name = string.Format("{0}, {1}", p.LastName, p.FirstName), 
     address = p.address 
    }); 

我有Serialize過載它調用Serialize(data, d => d);。狩獵「地圖」成員允許的東西,如:

mySerializer.Serialize(new { 
     employeeID = new { val = myEmployeeObject.ID, map = d => d.ToUpperCase() }, 
     employeeName = myEmployeeObject.Name 
    }); 
相關問題