我有两节课,BaseClass和Person.将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是类型BaseClass和item类型Person.为什么它不能推断T是typeof(Person),当它已经知道item是一个人吗?
我上面的例子是错误的,当我打电话给GetProperty时,我通过了this.
public class BaseClass
{
public void DoSomething()
{
var property = GetProperty(this, (property) => p.Name == "Name");
}
}
Run Code Online (Sandbox Code Playgroud)
出现此推理问题的原因是泛型推理发生在编译时,因此与手动指定所需类型相同。如果您切换到<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()这样更准确。
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |