将三元运算符与匿名函数一起使用时出现编译错误

本文关键字:一起 错误 编译 函数 三元 运算符 | 更新日期: 2023-09-27 18:17:46

这个让我感到困惑,所以我想我会在这里问,希望C#大师可以向我解释。

为什么此代码会生成错误?

        Func<IEnumerable<Item>, IEnumerable<Item>, IEqualityComparer<Item>, IEnumerable<Item>> func = strict ?
            (first, second, comparer) => first.Intersect(second, comparer) :
            (first, second, comparer) => first.Union(second, comparer);

虽然这个没有:

        Func<IEnumerable<Item>, IEnumerable<Item>, IEqualityComparer<Item>, IEnumerable<Item>> func1;
        if (strict)
            func1 = (first, second, comparer) => first.Intersect(second, comparer);
        else
            func1 = (first, second, comparer) => first.Union(second, comparer);

将三元运算符与匿名函数一起使用时出现编译错误

lambda 箭头=>

(first, second, comparer) => first.Intersect(second, comparer)

本身不具有类型。不过,它可以隐式转换为与签名和返回类型匹配的所有委托类型。它也(除了一些例外(转换为Expression<Del>Del是这样的代表。

当您将 lambda 箭头直接分配给 func1 变量时,编译器确切地知道要转换为哪种委托类型。所以这有效(你的第二个例子(。

在第一个示例中:

strict ?
(first, second, comparer) => first.Intersect(second, comparer) :
(first, second, comparer) => first.Union(second, comparer)

(在我们甚至来到func赋值之前(编译器首先必须在冒号:的每一侧找到两种类型中最好的通用类型。但是正如我所说,lambda 箭头没有类型,所以它会失败。如果你说:

strict ?
(Func<IEnumerable<Item>, IEnumerable<Item>, IEqualityComparer<Item>, IEnumerable<Item>>)((first, second, comparer) => first.Intersect(second, comparer)) :
(Func<IEnumerable<Item>, IEnumerable<Item>, IEqualityComparer<Item>, IEnumerable<Item>>)((first, second, comparer) => first.Union(second, comparer))

但这当然是丑陋的。(实际上,您只需强制转换两个 lambda 中的一个即可为其提供类型,然后另一个将自动获得相同的类型。

加法:

null关键字也发生了类似的事情,它本身也没有类型,但可以隐式转换为许多类型(如string(。所以这有效:

string myString1 = null;

虽然这些不会:

var myString2 = null;                    // need to cast null to a type, to use var
string myString3 = strict ? null : null; // cast at least one null, to use ternary op
它可能

与这个问题的原因相同

如果将"func1 = "添加到三元表达式中,则编译错误应该消失