Lambda表达式类型推理在继承链中是不同的.为什么?

本文关键字:是不同 为什么 继承 表达式 类型 推理 Lambda | 更新日期: 2023-09-27 17:58:07

给定以下类:

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"属性设置器中的lambda表达式推断基类的泛型类型,但对于Class3,编译器推断基类,而不仅仅是基类的泛型。为什么会这样?代码示例中推断类型的条件是什么。谢谢

Lambda表达式类型推理在继承链中是不同的.为什么?

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

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

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

Class2有一个名为TObject的类型参数,这完全是巧合——我认为您期望传递到该TObject中的任何东西都会传递到Class1,但事实并非如此。

如果您将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); }
    }
}
相关文章: