【问题标题】:How can I get the properties of an inherited object when the parameter is declared as a base type?当参数声明为基类型时,如何获取继承对象的属性?
【发布时间】:2015-04-17 23:15:53
【问题描述】:

我有一个简单的程序,它使用反射打印出所提供类的属性和值。

class BaseClass
{
    public string A
    {
        get { return "BaseClass"; }
    }
}

class Child1 : BaseClass
{
    public string Child1Name {
        get { return "Child1"; }
    }
}

class Child2 : BaseClass
{
    public string Child2Name
    {
        get { return "Child2"; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        var child1 = new Child1();
        var child2 = new Child2();
        SomeMethod(child1);
        SomeMethod(child2);

        Console.ReadKey();
    }

    static void SomeMethod(BaseClass baseClass)
    {
        PrintProperties(baseClass);
    }

    static void PrintProperties<T>(T entity)
    {
        var type = typeof(T);

        foreach (var targetPropInfo in type.GetProperties())
        {
            var value = type.GetProperty(targetPropInfo.Name).GetValue(entity);
            Console.WriteLine("{0}: {1}", targetPropInfo.Name, value);
        }
        Console.WriteLine("");
    }
}

问题在于它只打印出BaseClass 属性,因为我使用泛型并将BaseClass 传递给PrintProperties 方法。

输出:

A:基类

A:基类

如何访问子类的属性?我想要这样的输出:

A:基类
Child1Name: Child1

A:基类
Child2Name: Child2

【问题讨论】:

  • 试试typeof(T),而不是entity.GetType()GetType() 将返回对象的实际类型。
  • 这正是我想要的。谢谢
  • 主题涵盖在stackoverflow.com/questions/983030/… 中,但它并没有明确涵盖泛型的差异(以绝对初学者可以理解的方式),所以不要关闭为 dup。

标签: c# generics reflection


【解决方案1】:

这里的问题是您在PrintProperties 中使用typeof(T),但您示例中的TBaseClass,因为这是您从SomeMethod 提供的参数类型。

在您的示例中,删除SomeMethod,直接调用PrintProperties 方法即可。

更简单的方法是使用entity.GetType() 而不是typeof(T)。这样,无论泛型类型是什么,您都将始终获得对象的真实类型。

【讨论】:

    【解决方案2】:

    这里的问题是您使用泛型,然后提取泛型类型值的属性。

    泛型允许您执行一些在运行时(实际上是 JIT 时间)填写的元编码,但是对泛型的调用在编译时处理 泛型推断。因此,因为您使用BaseClass 类型的变量调用PrintProperties,所以T 总是被推断为BaseClass不是实际的运行时类型。

    有两种方法可以解决这个问题 - 一种是使用内置的 GetType() 方法,每个 object 都有。

    var type = entity.GetType();
    

    作为保证,您将拥有可以使用的运行时类型。

    另一个,对于需要完美泛型的进一步情况,是使用dynamic 对象传递给泛型方法,它允许运行时在运行时推断泛型类型,从而得到完全匹配的类型:

    static void SomeMethod(BaseClass baseClass)
    {
        PrintProperties((dynamic)baseClass);
    }
    

    【讨论】:

      【解决方案3】:

      typeof(T) 将返回该特定类型。这意味着当TBaseClass 时,您只会获得与其相关的属性。它不知道任何派生的东西。

      您要做的是将typeof(T) 替换为entity.GetType()GetType() 返回对象实例的实际类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-07
        • 2021-09-03
        • 2022-12-04
        • 1970-01-01
        • 2022-02-20
        • 1970-01-01
        • 2015-11-18
        相关资源
        最近更新 更多