这个让我感到沮丧,所以我想我会在这里问,希望C#guru可以向我解释。
为什么此代码会产生错误?
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);
答案 0 :(得分:1)
它可能与this question
中的原因相同如果将“func1 =”添加到三元表达式中,编译错误应该消失
答案 1 :(得分:1)
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