问题
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