为什么泛型类型不正确?

Joh*_*ger 5 c# generics

我有两节课,BaseClassPerson.将Person类从继承BaseClass.然后我使用以下通用方法.

    public static PropertyInfo GetProperty<T>(T item, Func<PropertyInfo, bool> predicate)
    {
        return GetProperty(typeof(T), predicate);
    }
Run Code Online (Sandbox Code Playgroud)

BaseClass我有一个方法,调用GetProperty

public class BaseClass
{
    public void DoSomething()
    {
        var property = GetProperty(new Person(), (property) => p.Name == "Name");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我从单元测试中调用此方法.

var person = new Person();
person.DoSomething();
Run Code Online (Sandbox Code Playgroud)

何时typeof(T)使用,BaseClass返回.如果我使用item.GetType()那么返回Person.如果我在调试器中检查它们,T是类型BaseClassitem类型Person.为什么它不能推断Ttypeof(Person),当它已经知道item是一个人吗?

编辑

我上面的例子是错误的,当我打电话给GetProperty时,我通过了this.

public class BaseClass
{
    public void DoSomething()
    {
        var property = GetProperty(this, (property) => p.Name == "Name");
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*vid 2

出现此推理问题的原因是泛型推理发生在编译时,因此与手动指定所需类型相同。如果您切换到<Person>通过调用显式声明,它会在编译期间引发错误吗?

解决这个问题的一种方法是确保您传入的变量(注意:不是对象!)是明确的类的Person,就像您的代码中一样。另一种方法是通过使用对象来强制在运行时进行通用推理dyanmic

GetProperty(this as dynamic, (prop) => prop.Name == "Name");
Run Code Online (Sandbox Code Playgroud)

通过在运行时使用确切的类型进行转换this as dynamic来调用。这种方法的问题在于,与其他对象相比,动力学极其缓慢。GetProperty<dynamic>this

如果您的模型严格是单级继承,您还可以利用静态多态性来处理通用参数。因此:

public class BaseClass<TSelf> where TSelf : BaseClass<TSelf>

public sealed class Model : BaseClass<Model>
Run Code Online (Sandbox Code Playgroud)

这样你就可以使用TSelf作为参数来代替T,并且它是完全正确的。这种方法的问题在于它严格限制您使用平面单继承层次结构,因为任何继承Model都会返回到原始问题并被视为 aModel因为它无法覆盖其基类使用的泛型参数。

假设您的 GetProperty 函数执行一些反射来检查属性,您可能需要考虑传入一个Type对象,而不是使用泛型 and then typeof(T),因为.GetType()这样更准确。