2010-08-10 27 views
6
public class Address 
{ 
    public string AddressLine1 { get; set; } 
    public string AddressLine2 { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
    public string Zip { get; set; } 
} 
...... 
var emp1Address = new Address(); 
emp1Address.AddressLine1 = "Microsoft Corporation"; 
emp1Address.AddressLine2 = "One Microsoft Way"; 
emp1Address.City = "Redmond"; 
emp1Address.State = "WA"; 
emp1Address.Zip = "98052-6399"; 

考虑上面的类以及稍后的初始化。现在在某些时候,我想记录错误发生时的状态。我想获得字符串日志有点像下面。记录对象的状态。获取其所有属性值作为字符串

string toLog = Helper.GetLogFor(emp1Address); 

sting toLog应该看起来像下面这样。

AddressLine1 = "Microsoft Corporation"; 
AddressLine2 = "One Microsoft Way"; 
City = "Redmond"; 
State = "WA"; 
Zip = "98052-6399"; 

然后我会登录toLog字符串。

如何在Helper.GetLogFor()方法中访问对象的所有属性名称和属性值?

解决方案,我来实现: -

/// <summary> 
/// Creates a string of all property value pair in the provided object instance 
/// </summary> 
/// <param name="objectToGetStateOf"></param> 
/// <exception cref="ArgumentException"></exception> 
/// <returns></returns> 
public static string GetLogFor(object objectToGetStateOf) 
{ 
    if (objectToGetStateOf == null) 
    { 
    const string PARAMETER_NAME = "objectToGetStateOf"; 
    throw new ArgumentException(string.Format("Parameter {0} cannot be null", PARAMETER_NAME), PARAMETER_NAME); 
    } 
    var builder = new StringBuilder(); 

    foreach (var property in objectToGetStateOf.GetType().GetProperties()) 
    { 
    object value = property.GetValue(objectToGetStateOf, null); 

     builder.Append(property.Name) 
     .Append(" = ") 
     .Append((value ?? "null")) 
     .AppendLine(); 
    } 
    return builder.ToString(); 
} 
+0

访问属性的名字是有某种原因不能使用序列化? – 2010-08-10 06:47:04

+0

我希望它具有人类可读的格式,以便每当我必须查看日志时,我都能够快速查看错误发生时对象的任何属性中的值。 – IsmailS 2010-08-11 04:57:50

回答

18
public static string GetLogFor(object target) 
{ 
    var properties = 
     from property in target.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) 
     select new 
     { 
      Name = property.Name, 
      Value = property.GetValue(target, null) 
     }; 

    var builder = new StringBuilder(); 

    foreach(var property in properties) 
    { 
     builder 
      .Append(property.Name) 
      .Append(" = ") 
      .Append(property.Value) 
      .AppendLine(); 
    } 

    return builder.ToString(); 
} 
+0

'参数typ'object'不能分配给builder.Append(property.Name).Append(“=”).AppendLine上的参数类型'string''编译错误(property.Value);'语句 – IsmailS 2010-08-10 05:59:45

+0

你能帮我理解'.GetProperties(BindingFlags.Public | BindingFlags.Instance)'是什么意思? – IsmailS 2010-08-10 06:10:33

+0

@Ismail:我已更新我的代码以删除该错误。我从来没有注意到'AppendLine'没有与'Append'相同的一组重载。 – 2010-08-10 06:34:04

5
static void Log(object @object) 
{ 
    foreach (var property in @object.GetType().GetProperties()) 
     Console.WriteLine(property.Name + ": " + property.GetValue(@object, null).ToString()); 
} 
+0

ToString调用将导致一个null属性值的'NullReferenceException'。 – 2010-08-10 04:59:05

+0

我必须在访问属性值之前进行空检查。 – IsmailS 2010-08-10 06:09:39

+0

我更喜欢这个答案,因为它不使用Linq – UpTheCreek 2016-06-16 15:09:42

1

可以使用反射 像下面

Type t = emp1Address.GetType(); 


PropertyInfo [] pi = t.GetProperties(); 
    foreach (PropertyInfo p in pi) 
    { 

    //You can get the value (using GetValue() method) and name (p.Name) here. 



    } 
相关问题