C# Lambda表达式类型推断在继承链中是不同的。为什么?

C# Lambda表达式类型推断在继承链中是不同的。为什么?,c#,lambda,type-inference,C#,Lambda,Type Inference,鉴于以下类别: 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>&

鉴于以下类别:

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); }
    }
}
公共类1{
受保护的void MethodA(表达式属性、ref TType存储、TType值){
}
}
公开课类别2:1{
私人物业;;
公共不动产{
获取{return\u propertyInt;}
集合{MethodA(c2=>c2.PropertyInt,ref _PropertyInt,value);}
}
}
公共类类别3:类别2{
私人浮动房地产贷款;
公共浮动房地产贷款{
获取{return\u propertyFloat;}
set{MethodA(c3=>c3.PropertyFloat,ref_PropertyFloat,value);}
}
}

对于类2,C#编译器在“PropertyInt”属性设置器中为lambda表达式推断基类的泛型类型,但对于类3,编译器推断基类,而不仅仅是基类的泛型类型。为什么会这样?代码示例中推断类型的条件是什么。谢谢。

首先,TObject泛型参数在Class1中定义。TObject在Class1中用作MethodA中的类型参数

在Class2中,传递给基(Class1)的TObject是Class2,因此lambda可以推断出局部属性_propertyInt

在Class3中,传递给基的TObject是Class2,而不是Class3。因此,lambda的参数是推断的,但它被推断为类2,而不是类3

Class2还有一个名为TObject的类型参数,这一事实完全是巧合——我认为您希望传递给该TObject的任何内容都能传递给Class1,而事实并非如此

如果您按照以下方式定义Class3,它将起作用:

public class Class3 : Class1<Class3> { ... }
公共类3:Class1{…}
如果给出了注释,那么我是否可以提供这种基于扩展方法的解决方案(假设类型参数仅用于实现此功能):

公共类1
{
}
公共静态类StaticClass1
{
公共静态void MethodA(此TZen zen,表达式属性,ref TType store,TType value),其中TZen:Class1
{
//在这里做任何事。。。
}
}
公开课类别2:1
{
私人物业;;
公共不动产
{
获取{return\u propertyInt;}
设置{this.MethodA(c2=>c2.PropertyInt,ref _PropertyInt,value);}
}
}
公共类类别3:类别2
{
私人浮动房地产贷款;
公共浮动房地产贷款
{
获取{return\u propertyFloat;}
设置{this.MethodA(c3=>c3.PropertyFloat,ref_PropertyFloat,value);}
}
}

Hmmm,克里斯,你说得对极了,无论链条有多深,TObject类型(在Class1中)始终是Class2。现在,我怎么会错过呢?不幸的是,您的解决方案在我的情况下不起作用,因为这意味着Class3将不再继承Class2的属性。最简单的解决方案是将C3转换为“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); }
    }
}