【问题标题】:Extension method on lambda expressionlambda 表达式的扩展方法
【发布时间】:2013-05-01 23:50:43
【问题描述】:

我有一个辅助方法,它获取由 lambda 定义的属性的名称,其工作原理如下:

ExpressionUtil.GetName((Thing t) => t.Property); // returns "Property"

我想把它变成一个扩展方法,所以语法是这样的:

((Thing t) => t.Property).GetName(); // wont compile : operator '.' cannot be applies to operand of type 'lambda expression'

但是我似乎不能这样做,因为((Thing t) => t.Property) 是一个 lambda(还不是表达式或 Func)。有没有办法编写直接应用于 lambda 的扩展方法?如果不是,为什么这是一件坏事?

【问题讨论】:

  • 你也可以施放它,但这看起来很糟糕。 :)
  • @rynah 是的,如果可能的话,我试图避免强制转换,将它放在扩展方法中的全部目的是让你更容易阅读你有点丢失的强制转换代码

标签: c# lambda extension-methods


【解决方案1】:

你不能这样做,因为 lambda 表达式本身没有类型;它的类型由上下文确定(例如,如果将其分配给委托变量或将其作为参数传递给方法)。

由于((Thing t) => t.Property) 没有类型,所以不能对其调用扩展方法,因为编译器不知道哪些扩展方法是有效的候选方法。

但是,您可以声明一个变量并在其上调用扩展方法:

Func<Thing, OtherThing> func = t => t.Property;
string name = func.GetName();

【讨论】:

  • 听上去我最好的选择就是为此找一个帮手,这让我有点难过。任何事情似乎都比它的价值更复杂
【解决方案2】:

您可以在 Action 上创建一个扩展方法,但成本较低,因此需要引入实例化。 我有时使用它并且代码是可读的。 这段代码存在的原因不太优雅,一个烂 NAS :-[

new Action(() =>
    {
        if (File.Exists(newFullPath))
            File.Delete(newFullPath);

        File.Move(oldFullPath, newFullPath);
    })
.Try(attemps: 2, exceptionValidator: (exception, attempt, attempts) =>
    {
        var throwIt = (attempt == attempts);
        if (!throwIt)
            Thread.Sleep(500);

        // .. tracing ./. throw
        return (throwIt);
    });

以防万一......即使帖子不年轻。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多