鉴于以下类别:
public class Class1<TObject> {
protected void MethodA<TType>(Expression<Func<TObject, TType>> property, ref TType store, TType value) {
}
}
public class Class2<TObject> : Class1<Class2<TObject>>{
private int _propertyInt;
public int PropertyInt {
get { return _propertyInt; }
set { MethodA(c2 => c2.PropertyInt, ref _propertyInt, value); }
}
}
public class Class3 : Class2<Class3> {
private float _propertyFloat;
public float PropertyFloat {
get { return _propertyFloat; }
set { MethodA(c3 => c3.PropertyFloat, ref _propertyFloat, value); }
}
}
对于Class2,C#编译器在'PropertyInt'属性setter中推断lambda表达式的基类的泛型类型,但对于Class3,编译器推断基类,而不仅仅是基类的泛型类型。为什么是这样?代码示例中的推断类型的标准是什么。感谢。
答案 0 :(得分:4)
首先,TObject泛型参数在Class1中定义。 那个 TObject在Class1中用作MethodA中的类型参数。
在Class2中,传递给基类(Class1)的TObject是Class2,因此lambda可以推断出本地属性_propertyInt。
在Class3中,传递给基类的TObject是Class2,而不是Class3。因此,推断出lambda的参数,但它被推断为Class2,而不是Class3。
Class2 还有一个名为TObject的类型参数的事实完全是巧合 - 我认为你期望传递给TObject的任何东西都会传递给Class1,而不是。 / p>
如果按如下方式定义了Class3,它将起作用:
public class Class3 : Class1<Class3> { ... }
鉴于评论,那么我可以提供这种基于扩展方法的解决方案,(假设类型参数仅用于实现此目的):
public class Class1
{
}
public static class StaticClass1
{
public static void MethodA<TZen, TType>(this TZen zen, Expression<Func<TZen, TType>> property, ref TType store, TType value) where TZen : Class1
{
// Do whatever here...
}
}
public class Class2 : Class1
{
private int _propertyInt;
public int PropertyInt
{
get { return _propertyInt; }
set { this.MethodA(c2 => c2.PropertyInt, ref _propertyInt, value); }
}
}
public class Class3 : Class2
{
private float _propertyFloat;
public float PropertyFloat
{
get { return _propertyFloat; }
set { this.MethodA(c3 => c3.PropertyFloat, ref _propertyFloat, value); }
}
}