【问题标题】:logging all properties of an object in c#. how to log inner object properties as well?在 c# 中记录对象的所有属性。如何记录内部对象属性?
【发布时间】:2014-12-06 19:45:41
【问题描述】:

我正在尝试 (1) 记录对象的所有属性,以及 (2) 其中特定对象类型的所有属性。我可以做(1)但不能做(2)。

现在就是这样。

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

我需要的是这样的:

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
}

但是,无论我尝试什么,第二件事都不起作用。所以,请帮忙。

更新 我对支票有答案(@Alex Art.)

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

现在唯一剩下的就是内部对象属性记录器了!

【问题讨论】:

    标签: c# properties inner-classes


    【解决方案1】:

    我认为可以通过使用反射来实现(但您应该注意性能损失):

    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));
           }
       }
    }
    

    我在这里也使用了递归,如果你有一些长的层次结构也可能会出现问题

    关于您的解决方案:

    // TODO 检查 object1 的当前属性是否为 object2 类型, 怎么样?

    您是否尝试过使用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
    

    【讨论】:

    • 那么,这对我的想法有影响吗?不可能吗?我真的很喜欢我的 foreach(PropertyDescriptor... 因为这里的性能是一个问题;)
    • 是的。那个如果有效。 thnx
    • 顺便说一句,我刚刚发现 TypeDescriptor 是建立在反射引擎之上的 (msdn.microsoft.com/en-us/library/ms171819.aspx),所以使用它时性能没有任何提升:-)
    • 有人甚至说纯反射更快(这是有道理的):stackoverflow.com/questions/7573913/…
    【解决方案2】:

    如果这是为了在运行时记录对象的状态,您可能会发现serialize the whole object as JSON 并存储它更容易。与自定义解决方案相比,这具有人类可读和更灵活的额外好处。

    要忽略某些属性,请将 IgnoreDataMemberAttribute 应用于它们。

    [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());
        }
    }
    

    【讨论】:

    • 我会使用它,但我收到此错误(由于使用 datetime.min):转换为 UTC 时大于 DateTime.MaxValue 或小于 DateTime.MinValue 的 DateTime 值无法序列化为JSON。我也无权访问该对象,因此无法使用注释对其进行更改。
    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    相关资源
    最近更新 更多