隐式运算符和 lambda

Posted

技术标签:

【中文标题】隐式运算符和 lambda【英文标题】:Implicit Operators and lambdas 【发布时间】:2014-03-18 17:32:03 【问题描述】:

我正在尝试创建一个接受 lambda 并将其存储在内部的类。语法类似于:

class Lambda<TIn, TOut> 
    private Expression<Func<TIn, TOut>> expr;
    private Func<TIn, TOut>> func;

    public Lambda(Expression<Func<TIn, TOut>> e) 
        expr = e;
    

    public Lambda(Func<TIn, TOut> f) 
        func = f;
    

    public static implicit operator Lambda<TIn, TOut>([lambdatype] o) 
        return new Lambda(o);
    

用法:

Lambda<TIn, TOut> l = o => ... ;

但我在搞清楚细节时遇到了一些麻烦。我知道 lambda 是匿名类型,直到它被分配给表达式或委托,并且我(我相信)必须使用隐式运算符来获得我想要的语法,但除此之外我已经击中一堵墙。如果它们已经被分配给这样的变量,我可以在我的隐式运算符中使用 Expression 或 Func:

Expression<Func<T1, T2>> e = o => ...;
Func<T1, T2> f = o => ...;

Lambda<T1, T2> l1 = e, l2 = f;

但我更愿意只分配 lambda 本身并让班级找出细节。

【问题讨论】:

【参考方案1】:

你的问题是C#语言does not chain user-defined implicit conversions。

Lambda 表达式是无类型表达式,隐式转换为(可能无限)兼容的委托和表达式树类型集。 (参见规范的§6.5)

您不能同时调用该隐式转换和用户定义的从委托类型到您自己的类型的隐式转换。

相反,您可以显式创建类型化委托:

Lambda<TIn, TOut> l = new Func<TIn, TOUt>(o => ... );

您还可以要求 C# 语言团队为用户定义的从方法组或 lambda 到任何类型的隐式转换定义语法。

【讨论】:

啊,我希望避免这种情况 :( 好的,谢谢您的回复! @SLaks - 我正在尝试为类型转换编写隐式运算符。从显式类型完全可行,但我试图将运算符抽象为可以放置运算符的基本类型(例如 BaseViewModel )。对于黄带程序员来说,这甚至是可能的还是只是一个白日梦?如果值得单独提出一个问题,请告诉我,我会发布一个。 @SLaks - 或者一个接口,如果可能的话......只是强制实现运算符以进行类型转换......在这种情况下,继承自 BaseViewModelTViewModel 类是强制实现运算符并定义转换(例如this.Prop1 = that.Prop1;【参考方案2】:

当您实际定义 lambda 表达式时,它需要是显式的(例如 Action 或 Func 等)。如果你这样做,你可以直接分配给委托类型的属性。

 public class myClass
 
     public Delegate myDelegate  get; set; 

     public myClass(Delegate d)
     
         myDelegate = d;
     
 


 myClass myInstance = new myClass(new Func<int, int>(x => x * x));

【讨论】:

以上是关于隐式运算符和 lambda的主要内容,如果未能解决你的问题,请参考以下文章

了解 Lambda 闭包类型如何删除默认构造函数

隐式移动构造函数和赋值运算符

显示转换和隐式转换

C# 隐式转换和 == 运算符

[深入06] 隐式转换 和 运算符

用户定义的隐式转换运算符和重载解析