【问题标题】:Implicit conversion from lambda expression to user-defined type从 lambda 表达式到用户定义类型的隐式转换
【发布时间】:2015-04-28 10:25:19
【问题描述】:

我想定义从(特定)lambda 表达式到用户定义类型的隐式转换。我尝试了以下方法:

public static implicit operator DualElement<T>(Func<OPTatom, OPTatom, T> atomMap)
{
    return new DualElement<T>(e => atomMap(e[0],e[1]));
}

然后我尝试了

DualElement<double> dubidu = (i, j) => cost[i, j];

给出“无法转换 lambda 表达式...因为它不是委托类型”

相反,有效的是:

DualElement<double> dideldu = (Func<OPTatom, OPTatom, double>)((i, j) => cost[i, j]);

我猜,lambda 表达式没有“Func”类型,所以我必须在隐式转换中加入一些不同的东西。

有人可以给我一个提示吗?

【问题讨论】:

  • DualElement 的定义是什么?
  • @Sajjad:我有不同的 lambda 表达式,它们“意味着”是从 OPTelement 类型的元素到 T 的函数。我的目标是将它们隐式转换为相同的类型,这样我就没有根据 DualElement 的来源重载每个方法。

标签: c# lambda implicit-conversion


【解决方案1】:

您的解决方法非常好。
Lambda 本身没有类型,因此应该将它们转换为某种适当的类型。
请看MSDN:

请注意,lambda 表达式本身没有类型,因为通用类型系统没有“lambda 表达式”的内在概念。然而,非正式地谈论 lambda 表达式的“类型”有时会很方便。在这些情况下,类型是指 lambda 表达式转换为的委托类型或 Expression 类型。

这就是以下示例无法编译的原因:

var func = (i, j) => i + j;

【讨论】:

  • @JenishRabadiya 我认为 OP 正试图将 lambda 分配给 DualElement。但是 lambdas 没有类型。因此初步将 lambda 转换为 Func 会有所帮助。而且我的示例无法编译,你自己试试吧。
  • @JenishRabadiya 实际上,OP 希望通过使用隐式运算符来实例化 DualElement,就像在 Linq-to-XML 中一样,您可以使用 XName foo = "bar"
  • 这是否意味着在 C# 中无法将 lambda 表达式隐式转换为其他类型?
  • @JFMeier 不,这在 C# 中是可能的,但在强制转换运算符重载中是不可能的,因为编译器无法确定正确的 lambda 类型。想象一下,对于具有相同签名的两种不同委托类型,您有两个不同的强制转换运算符。 Lambda 可以转换为任何这些委托类型。用哪一个?
【解决方案2】:

您已经从 Func&lt;OPTatom, OPTatom, T&gt; 委托类型定义了隐式运算符,并尝试从 C# 编译器看起来很奇怪的 lambda 表达式进行转换。

而是将 lambda 表达式存储在某个 Func&lt;OPTatom, OPTatom, T&gt; 类型的变量中,然后执行隐式转换。 以下将在这里工作:

Func<OPTatom, OPTatom, T> temp = (i, j) => cost[i, j];
DualElement<double> dubidu = temp;

我创建了演示,效果很好。

public class Program
{
    public static void Main()
    {
        Func<string, bool> func = d => true;
        Process<bool> p = func;
        //Process<bool> p = d => true; would result in error
    }
}

public class Process<T>
{
    public Process(T item)
    {
        Item = item;
    }

    public T Item
    {
        get;
        set;
    }

    public static implicit operator Process<T>(Func<string, T> func)
    {
        return new Process<T>(func("jenish"));
    }
}

Here 是 dotnetfiddle 链接,以防你想玩它。

【讨论】:

  • 谢谢。但我最初的目标是使用不同的 lambda 表达式作为方法的参数。目前,我为每个使用 DualElement 的方法编写了四个重载方法,因为我想要一种简单的方法使用方法(就 lambda 表达式而言)。我试图避免这种翻两番,但显然,这是不可能的。
猜你喜欢
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多