[英]How to search through nested properties of T to set base class property
I have an XML serialiser that breaks when the XML returned isn't valid XML. 我有一个XML序列化程序,当返回的XML无效XML时中断。 So to combat this I wanted to display the error in the object returned rather than just null or break.
因此,为了解决这个问题,我想在返回的对象中显示错误,而不仅仅是null或break。
One of my classes is derived from a class that contains a string error property called message
, it is this property I wish to set so that the error message can be seen. 我的一个类派生自一个类,该类包含一个称为
message
的字符串错误属性,我希望设置该属性以便可以看到错误消息。
Class structure could be two or three classes down. 班级结构可以减少两到三个班级。 Using generic reflection, I wish to access the string property,
message
, of ClassC when I parse in either Class1 or ClassA. 使用通用反射,当我在Class1或ClassA中进行解析时,我希望访问ClassC的字符串属性
message
。
Is it possible to access the Message property of ClassC? 是否可以访问ClassC的Message属性? Currently when I send in an object that doesn't directly derive from ClassC it throws an exception because it cannot find the property (which doesn't exist in ClassA||1), however as not every class will be
ClassA -> ClassB : ClassC
, some could be Class1 -> Class2 -> Class3 : ClassC
当前,当我发送一个不是直接从ClassC派生的对象时,它会引发异常,因为找不到属性(在ClassA || 1中不存在),但是由于并非每个类都是
ClassA -> ClassB : ClassC
,有些可能是Class1 -> Class2 -> Class3 : ClassC
Problem code: - I can only see the properties of the object parsed into the function, I need to be able to iterate through all of the properties, initialise if they are not already until I find the string property called message
so I can set it and return an object containing useful error information. 问题代码: -我只能看到解析为函数的对象的属性,我需要能够遍历所有属性,如果还没有初始化,请进行初始化,直到找到名为
message
的字符串属性,以便进行设置并返回一个包含有用错误信息的对象。
var obj = (T)Activator.CreateInstance(typeof(T));
Type type = obj.GetType();
PropertyInfo prop = type.GetProperty("message");
prop.SetValue(obj, Convert.ChangeType(dirtyXml,prop.PropertyType), null);
return (T)obj;
Desired - for the message property within ClassC to be accessible to be set against. 所需 -可以设置ClassC中的message属性。 At present I need to initialise the other properties (that are classes), so ClassB or Class2 and Class3, before I can get to the message property.
目前,在获取message属性之前,需要初始化其他属性(即类),即ClassB或Class2和Class3。 However I don't know which object will be passed into the function.
但是我不知道哪个对象将被传递到函数中。
Two tier class structure: 两层类结构:
Class ClassA
{
public ClassB classB { get; set; }
}
Class ClassB : ClassC
{
// other properties
}
Class ClassC
{
public String message { get; set; }
{
I think you don't really want to find a randomly-typed object with a message
property - you specifically want to find an object derived from ClassC
. 我认为您并不是真的想找到一个具有
message
属性的随机类型的对象-您特别想找到一个从ClassC
派生的对象。 So you'd be better with something like this, which looks down the hierarchy of properties until it finds something derived from ClassC
: 因此,使用类似这样的方法会更好,该方法会向下查看属性的层次结构,直到找到从
ClassC
派生的内容ClassC
:
using System;
public class Program
{
class ClassA
{
public ClassB classB { get; set; }
}
class ClassB : ClassC
{
}
class ClassC
{
public string message { get; set; }
}
static T FindClass<T>(object obj) where T : class
{
var classType = obj.GetType();
var targetType = typeof(T);
if (IsDerivedFrom(classType, targetType))
{
return (T)obj;
}
foreach (var prop in classType.GetProperties())
{
if ( prop.PropertyType.IsClass)
{
var childObj = prop.GetValue(obj);
var target = FindClass<T>(childObj);
if (target != null)
{
return target;
}
}
}
return null;
}
static bool IsDerivedFrom(Type class1, Type class2)
{
return class2.IsAssignableFrom(class1);
}
public static void Main()
{
var classA = new ClassA { classB = new ClassB() };
classA.classB.message = "Hello";
var classC = FindClass<ClassC>(classA);
if (classC != null)
{
Console.WriteLine(classC.message);
}
}
}
(Take a look at this fiddle to see it in action). (看看这个小提琴 ,看看它的作用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.