lambda 表达式如何与隐式转换一起使用?

问题描述 投票:0回答:1

我对 C# 如何处理隐式转换的 lambda 表达式有点困惑。

我的目标类似于以下最小示例:

A<int>.DoSomething(x => x == 42);

public static class A<T>
{
    public static void DoSomething(PredicateAdapter<T> _) { }
}

public class PredicateAdapter<T>
{
    public static implicit operator PredicateAdapter<T>(Predicate<T> _) => new();
}

所以我想为谓词创建一个包装器,它允许我做一些奇特的事情(为了简洁起见,在本示例中没有列出。)但是,上面的代码无法编译,因为“Error CS1660:无法将 lambda 表达式转换为类型“PredicateAdapter”,因为它不是委托类型”。

相反,下面是隐式转换起作用的示例:

A<int>.DoSomething(x => x == 42);

public static class A<T>
{
    public static void DoSomething(Predicate<T> _) { }
}

编译器能够推断 lambda 表达式

x => x == 42
可以隐式转换为
Predicate<int>
并将其愉快地传递给
A<int>.DoSomething(Predicate<int>)

此外,将 lambda 显式转换为

Predicate<int>
意味着我的自定义隐式转换已应用并且有效:

A<int>.DoSomething((Predicate<int>)(x => x == 42));

public static class A<T>
{
    public static void DoSomething(PredicateAdapter<T> _) { }
}

public class PredicateAdapter<T>
{
    public static implicit operator PredicateAdapter<T>(Predicate<T> _) => new();
}

所以,我的问题是:当 C# 显然能够隐式执行此转换时,为什么我需要显式转换 lambda(并编写可读性低得多的代码)?并且:是否可以以某种方式修改类

A
PredicateAdapter
,以便我可以使用简单的 lambda 表达式(无需任何显式转换)并仍然使用
PredicateAdapter

c# lambda implicit-conversion
1个回答
0
投票

根据我的理解,这是“因为规范是这么说的”。正如 12.19 匿名函数表达式 部分所述:

匿名函数本身没有值或类型,但可以转换为兼容的委托或表达式树类型。

因此,当您使用匿名函数(lambda 表达式)时,编译应该决定它应该是什么类型(因为您没有显式指定类型)。因为您的参数不是委托类型(如

Predicate<T>
)或表达式树类型(即
Expression<Func<T, TResult>>
)。

同样来自 10.7 匿名函数转换

anonymous_method_expression
lambda_expression
被归类为匿名函数(第 12.19 节)。该表达式没有类型,但可以隐式转换为兼容的委托类型。某些 lambda 表达式也可以隐式转换为兼容的表达式树类型。

C# 10 中的 Lambda 改进 也很有趣。

© www.soinside.com 2019 - 2024. All rights reserved.