为什么'Predicate< T>'与'Func< T,bool>'不匹配? [英] Why a `Predicate<T>` doesn't match a `Func<T,bool>`?

查看:189
本文介绍了为什么'Predicate< T>'与'Func< T,bool>'不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在C#中编译以下代码:

  public static T FirstEffective(IEnumerable< T> list)
{
谓词< T> pred = x => x!= null;
返回Enumerable.FirstOrDefault(list,pred);

编译器(Mono / .NET 4.0)给出了以下错误: p>

  File.cs(139,47)System.Linq.Enumerable.FirstOrDefault< T>的最佳重载方法匹配.Collections.Generic.IEnumerable< T>,System.Func< T,bool>)'有一些无效参数
/usr/lib/mono/4.0/System.Core.dll(与之前相关的符号的位置错误)
File.cs(139,47):错误CS1503:参数`#2'无法将`System.Predicate< T>'表达式转换为类型'System.Func< T,bool>'

由于 Predicate< T> 在实际上是一个函数,它以一个参数 T 作为输入并返回一个 bool T 甚至是协变的,因此允许专门化 T )。代表是否考虑了Liskov替代原则,以推导出 Predicate< T> 相当于 Func< T,bool> ?据我所知,这个等价问题应该是可以决定的。

解决方案

C#规范很明确:


15.1委托声明



C#中的委托类型与名称等同,结构上相同。
具体而言,具有相同
参数列表和返回类型的两种不同委托类型被视为不同委托
类型。
blockquote>

这就是为什么你的代码不能编译。



你可以通过调用委托而不是传递它:

  public static T FirstEffective(IEnumerable< T> list){
Predicate< T> pred = x => x!= null;
返回Enumerable.FirstOrDefault(list,x => pred(x));
}

更新
$ b

Eric Lippert写了一篇很棒的博客文章:C#团队的前任成员是微软,他非常详细地回答您的问题:代表和结构特征

I try to compile the following code in C#:

public static T FirstEffective(IEnumerable<T> list) 
{
    Predicate<T> pred = x => x != null;
    return Enumerable.FirstOrDefault(list, pred);
}

The compiler (Mono/.NET 4.0) gives the following error:

File.cs(139,47) The best overloaded method match for `System.Linq.Enumerable.FirstOrDefault<T>(this System.Collections.Generic.IEnumerable<T>,System.Func<T,bool>)' has some invalid arguments
/usr/lib/mono/4.0/System.Core.dll (Location of the symbol related to previous error)
File.cs(139,47): error CS1503: Argument `#2' cannot convert `System.Predicate<T>' expression to type `System.Func<T,bool>'

This is rather strange since a Predicate<T> is in fact a function that takes as input a parameter T and returns a bool (T is even "covariant" thus a specialization of T is allowed). Do delegates do not take the "Liskov Substitution principle" into account to derive that Predicate<T> is equivalent to Func<T,bool>? As far as I know this equivalence problem should be decidable.

解决方案

C# specification is clear about that:

15.1 Delegate declarations

Delegate types in C# are name equivalent, not structurally equivalent. Specifically, two different delegate types that have the same parameter lists and return type are considered different delegate types.

That's why your code doesn't compile.

You can make it work by calling the delegate, instead of passing it:

public static T FirstEffective (IEnumerable<T> list) {
    Predicate<T> pred = x => x != null;
    return Enumerable.FirstOrDefault (list, x => pred(x));
}

Update

There is a great blog post by Eric Lippert: former member of C# Team as Microsoft, which answers your question in much details: Delegates and structural identity.

这篇关于为什么'Predicate&lt; T&gt;'与'Func&lt; T,bool&gt;'不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆