简体   繁体   English

当参数声明为基类型时,如何获取继承对象的属性?

[英]How can I get the properties of an inherited object when the parameter is declared as a base type?

I have a simple program that uses reflection to print out the properties and values of the supplied class. 我有一个简单的程序,它使用反射打印出提供的类的属性和值。

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

The problem is that it only prints out the BaseClass properties because I am using generics and passing in the BaseClass into the PrintProperties method. 问题是它只打印出BaseClass属性,因为我使用泛型并将BaseClass传入PrintProperties方法。

Output: 输出:

A: BaseClass 答:BaseClass

A: BaseClass 答:BaseClass

How do I access the properties of the Child classes? 如何访问Child类的属性? I would like an output like: 我想要一个输出像:

A: BaseClass 答:BaseClass
Child1Name: Child1 Child1Name:Child1

A: BaseClass 答:BaseClass
Child2Name: Child2 Child2Name:Child2

The problem here is that you're using typeof(T) in PrintProperties , but the T in your example is BaseClass because that's the type of the parameter you give it from SomeMethod . 这里的问题是你在PrintProperties使用typeof(T) ,但是你的例子中的TBaseClass因为这是你从SomeMethod给出的参数的类型。

In your example, remove SomeMethod , call the PrintProperties method directly and it'll work. 在您的示例中,删除SomeMethod ,直接调用PrintProperties方法,它将工作。

A simpler way would be to use entity.GetType() instead of typeof(T) . 一种更简单的方法是使用entity.GetType()而不是typeof(T) That way, no matter what the generic type is, you'll always get the true type of the object. 这样,无论泛型类型是什么,您都将始终获得对象的真实类型。

The issues here is that you're using generics and then pulling out the properties of the generic type's value. 这里的问题是你使用泛型然后提取泛型类型值的属性。

Generics allow you to do some metacoding that's filled out at runtime (actually JIT-time) however the calls to generics deal with generic inferencing at compile time. 泛型允许您执行在运行时填充的一些元编码(实际上是JIT时间),但是对泛型的调用在编译时处理泛型推理 Thus, because you call PrintProperties with a variable of type BaseClass , the T is always inferred to be BaseClass , not the actual runtime type. 因此,因为您使用BaseClass类型的变量调用PrintProperties ,所以始终将T推断为BaseClass而不是实际的运行时类型。

There are two ways around this - one is to use the built in GetType() method that every object has. 有两种方法 - 一种是使用每个 object都有的内置GetType()方法。

var type = entity.GetType();

As this garunantees you'll have the runtime type to work with. 作为这个garunantees你将有运行时类型。

The other, for further cases of needing a perfect generic, is to pass to the generic method using a dynamic object, which allow the runtime to infer the generic type at runtime and thus get the exactly matching type: 另一方面,对于需要完美泛型的其他情况,是使用dynamic对象传递给泛型方法,这允许运行时在运行时推断泛型类型从而获得完全匹配的类型:

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

typeof(T) will return you that specific type. typeof(T)将返回该特定类型。 This means when T is BaseClass you are only ever going to get properties related to it. 这意味着当TBaseClass您只会获得与之相关的属性。 It does not know about anything derived. 它不知道任何派生的东西。

What you do instead is replace typeof(T) with entity.GetType() . 你要做的是用entity.GetType()替换typeof(T) entity.GetType() GetType() returns you the actual type of the object instance. GetType()返回对象实例的实际类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 可以使用基本类型声明参数 - Parameter can be declared with base type Ninject:当属性标记了继承类型时,如何获取继承类型而不是基类型 - Ninject : How Get inherited type instead Base type when inherited type marked by attribute 在继承的类中向下转换在基类中声明的对象 - Downcast an object, that is declared in a base class, in the inherited class 如何访问 WCF 中继承的 object 属性? - How to get access to inherited object properties in WCF? 如何设置一个参数,该参数接受以后要声明的对象? - How can I set a parameter that accepts an object to be declared later on? “IEnumerable 的可能多重枚举”与“参数可以用基类型声明” - “Possible multiple enumeration of IEnumerable” vs “Parameter can be declared with base type” 在子类中声明时如何调用继承函数执行 - How can I call an Inherited function to execute when declared in child class 如何避免继承的类必须传递基类的构造函数参数 - How can I avoid that the inherited class have to pass the base class constructor parameter 在参数中声明IDisposable时如何处理它? - How can i dispose IDisposable when it is declared in a parameter? 返回基类型时从继承中获取值 - Get Values from inherited when base type is given back
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM