logging all properties of an object in c#. how to log inner object properties as well?

泄露秘密 提交于 2021-01-27 15:50:27

问题


i am trying to (1) log all properties of an object, and (2) all properties of a specific object type within. i can do the (1) but not (2).

this is the case now.

foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(object1))
{
     string name = descriptor.Name;
     object value = descriptor.GetValue(object1);
     logger.Debug(String.Format("{0} = {1}", name, value));
}

what i need is something like:

foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(object1))
{
     string name = descriptor.Name;
     object value = descriptor.GetValue(object1);
     logger.Debug(String.Format("{0} = {1}", name, value));

     // TODO check if the current property of object1 is of type object2, how?
     if (...) {
     // TODO repeat the process for object2

     foreach (PropertyDescriptor innerdescriptor in TypeDescriptor.GetProperties(object2))
     {
          string innername = innerdescriptor.Name;
          object innervalue = innerdescriptor.GetValue(object2);
          logger.Debug(String.Format("     {0} = {1}", innername, innervalue));
     }

     } // end if
}

however, this second thing doesn't work no matter what i try. so, please help.

update i have an answer (by @Alex Art.) to the check

if (descriptor.PropertyType == typeof(the type that you expecting) )  { ... }

now the only thing that remains is the inner object properties logger!


回答1:


I think it can be achieved by using reflection (But you should be aware of performance penalty):

public void LogProps(Object object1)
{
   var objType = object1.GetType();

   IList<PropertyInfo> properties = new List<PropertyInfo>(objType.GetProperties());

   foreach (PropertyInfo prop in properties)
   {
       var propValue = prop.GetValue(object1, null);
       if(prop.PropertyType == typeof(yourTypeHere))
       {  
          LogProps(propValue);
       }
       else
       {           
           logger.Debug(String.Format("{0} = {1}", prop.Name, propValue));
       }
   }
}

I also used a recursion here which is also could be problematic if you have some long hierarchy

Regarding your solution:

// TODO check if the current property of object1 is of type object2, how?

Did you try using PropertyDescriptor.PropertyType?:

 object value = descriptor.GetValue(object1);

 if (descriptor.PropertyType == typeof(the type that you expecting) ) 
 {

    foreach (PropertyDescriptor innerdescriptor in TypeDescriptor.GetProperties(value) 
    {
         string innername = innerdescriptor.Name;
         object innervalue = innerdescriptor.GetValue(object2);
         logger.Debug(String.Format("     {0} = {1}", innername, innervalue));
    }

 } // end if



回答2:


If this is for the purpose of logging the state of the object at runtime, you'll probably find it easier to serialize the whole object as JSON and store that instead. This has the added benefit of being human readable and more flexible than a custom solution.

To ignore certain properties, apply the IgnoreDataMemberAttribute to them.

i.e.

[DataContract]
public class MyObjectParent
{
    [DataMember]
    public int ImportantValue { get; set; }

    [DataMember]
    public MyObjectChild Child { get; set; }

    [IgnoreDataMember]
    public AnotherClassThatIWantToIgnore IgnoreMe { get; set; }
}

[DataContract]
public class MyObjectChild
{
    [DataMember]
    public string ImportantValue { get; set; }   
}

public string ObjectAsJson<T>(T obj) where T : class
{
    var serializer = new DataContractJsonSerializer(typeof(T));
    using (var stream = new MemoryStream())
    {
       serializer.WriteObject(stream, obj);
       return Encoding.Default.GetString(stream.ToArray());
    }
}


来源:https://stackoverflow.com/questions/27330935/logging-all-properties-of-an-object-in-c-how-to-log-inner-object-properties-as

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!