【问题标题】:How to search through nested properties of T to set base class property如何搜索 T 的嵌套属性以设置基类属性
【发布时间】:2016-01-11 12:44:18
【问题描述】:

我有一个 XML 序列化程序,当返回的 XML 不是有效的 XML 时会中断。因此,为了解决这个问题,我想在返回的对象中显示错误,而不仅仅是 null 或 break。

我的一个类派生自一个包含名为message 的字符串错误属性的类,我希望设置此属性以便可以看到错误消息。

类结构可以是两个或三个类。使用泛型反射,我希望在解析 Class1 或 ClassA 时访问 ClassC 的字符串属性message

是否可以访问 ClassC 的 Message 属性?目前,当我发送一个不直接从 ClassC 派生的对象时,它会引发异常,因为它找不到该属性(ClassA||1 中不存在该属性),但是由于并非每个类都是ClassA -> ClassB : ClassC,所以有些可能是Class1 -> Class2 -> Class3 : ClassC

问题代码: - 我只能看到解析到函数中的对象的属性,我需要能够遍历所有属性,如果它们还没有初始化,直到我找到名为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 - 用于设置 ClassC 中的 message 属性。目前我需要初始化其他属性(即类),例如 ClassB 或 Class2 和 Class3,然后才能访问消息属性。但是我不知道将哪个对象传递给函数。

两层类结构:

Class ClassA 
{
    public ClassB classB { get; set; }
}

Class ClassB : ClassC 
{
    // other properties 
}

Class ClassC 
{
    public String message { get; set; }
{

【问题讨论】:

  • “它坏了”是什么意思?
  • @GaryMcGill - 这是一个未处理的异常,所以程序崩溃了,我希望将字符串错误放在类属性消息中,以便可以返回错误。
  • 你说“当我发送一个不是从 ClassC 派生的对象时,它会中断”,但大概你的意思是它确实ClassC 派生,但它这样做是间接
  • 好点,是的,我的意思是它确实直接从 classC 派生,因此将发送 ClassA,但我需要访问 ClassC 属性 - 干杯,错过了,将更新 Q。
  • 你得到了什么具体的异常,在哪一行?

标签: c# generics reflection


【解决方案1】:

我认为您并不是真的想找到一个具有message 属性的随机类型对象——您特别想找到一个派生自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);
        }
    }
}

(查看this fiddle 以了解它的实际效果)。

【讨论】:

  • 谢谢你的好先生,太棒了!不知道你能找到这样的派生类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多