gpt4 book ai didi

c# - 将函数分配给表达式,反之亦然

转载 作者:IT王子 更新时间:2023-10-29 04:42:26 25 4
gpt4 key购买 nike

我在篡改表达式,在某些时候我感到困惑

  1. 我们可以将相同的 LamdaExpression 分配给 Expression 和/或 Func。但是我们不能将 Func 分配给 Expression(或将 Expression 分配给 Func)。为什么我们不能那样做?我寻找是否定义了 Expression 和 Func 之间的转换运算符,但我找不到。

    Func<int, int> sumFunc            = i => i + i;
    Expression<Func<int, int>> sumExp = i => i + i;

    // sumExp = sumFunc; // Cannot convert source type 'System.Func<int,int>' to target type 'System.Linq.Expressions.Expression<System.Func<int,int>>'
    // sumFunc = sumExp; // Cannot convert source type 'System.Linq.Expressions.Expression<System.Func<int,int>>' to target type 'System.Func<int,int>'
  2. 即使我们不能将 LambdaExpression 分配给对象。同样,为什么我们不能这样做?

    // object o = i => i + i; // Cannot convert source type 'lambda expression' to target type 'object'
  3. 我认为编译器有些问题。如果是这样,我们能否编写以这种(令人困惑的)方式表现的自定义类型并利用某些东西。

最佳答案

关于 C# Language Specification像这样的 lambda 表达式

i => i + i

是一个匿名函数。具有此分类的表达式可以隐式转换为兼容的委托(delegate)类型或表达式树类型。这就是为什么你可以同时写这两个

Func<int, int> sumFunc            = i => i + i;
Expression<Func<int, int>> sumExp = i => i + i;

第一个是委托(delegate)类型,第二个是表达式树类型。因为这些类型之间没有隐式转换,所以您不能分配 sumFunc = sumExp ,反之亦然。但是由于表达式树 sumExp 表示一个 lambda 表达式,您可以将该表达式编译为可执行委托(delegate)并将其分配给 sumFunc,因为这是一个兼容的委托(delegate):

sumFunc = sumExp.Compile();

另一个方向是不可能的,因为委托(delegate)不能轻易地“反编译”成表达式树。

不会写的原因

object o = i => i + i;

是,匿名函数本身没有值或类型,它只是可转换为委托(delegate)或表达式树类型。你必须告诉编译器你想要两者中的哪一个,所以你可以先转换它,然后将结果分配给 object 类型的变量:

object sumFuncObject = (Func<int, int>) (i => i + i);
object sumExpObject = (Expression<Func<int, int>>) (i => i + i);

关于您的最后一个问题:您可以在复杂类型之间创建自定义隐式或显式转换,以便可以将这种“魔法”应用于赋值。查看Conversion Operations Programming Guide获取更多信息。

关于c# - 将函数分配给表达式,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14175514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com