有人可以解释在C#中使用Action<T>
和Predicate<T>
作为代表的确切原因是什么
答案 0 :(得分:11)
您是在问他们为什么存在,或者为什么他们被定义为代表?
至于它们存在的原因,也许最好的理由是方便。如果你想要一个不返回值的委托并且只接受某种类型的单个参数,你可以自己定义它:
public delegate void MyDelegate(int size);
然后再创建一个:
MyDelegate proc = new MyDelegate((s) => { // do stuff here });
当然,你必须为你想拥有这种方法的每种不同类型做到这一点。
或者,您可以使用Action<T>
:
Action<int> proc = new Action<int>((s) => { /* do stuff here */ });
当然,您可以将其缩短为:
Action<int> proc = (s) => { /* do stuff here */ });
至于“他们为什么代表?”因为这是在.NET中操作函数引用的方式:我们使用委托。请注意上面示例中的相似之处。也就是说,MyDelegate
在概念上与Action<int>
相同。它们不是完全相同的东西,因为它们有不同的类型,但您可以轻松地用MyDelegate
替换程序中Action<int>
的每个实例,程序将工作
答案 1 :(得分:4)
他们还会是什么?委托是最灵活和最接近的Action<T>
,Predicate<T>
和Func<T>
模型匹配 - 具有指定参数类型(也称为委托)的调用列表。
答案 2 :(得分:3)
解释为什么选择使用Action<T>
和Predicate<T>
代表执行操作和谓词操作的习惯用法的最佳方法是首先考虑替代方法。没有代表,你怎么能完成同样的事情?接下来最好的事情是拥有接口IAction
和IPredicate
,并强制开发人员声明一个类,并为所需的每种不同类型的操作实现适当的接口。但是,这种方法的问题在于它需要更多的努力,更多的类扩散和更少的可维护代码。委托方法更方便,因为您可以使用匿名方法或lambda表达式将逻辑内联到将使用的位置。
答案 3 :(得分:2)
因为他们是代表。
答案 4 :(得分:1)
你是从错误的角度看问题。
问题不应该是“为什么Action<>
,Func<>
和Predicate<>
代表?” (答案是“因为他们需要”)
真正的问题是,“为什么我们有特定的命名对象来处理简单的委托任务?为什么在普通代表可以使用的地方使用Action<>
?”
答案是那些特定的委托在CLR本身上被大量使用,并且因为它们被用在CLR方法中,其中最终开发人员必须定义被调用的方法,委托的声明必须是上市。因此,Microsoft可以定义数千个委托,每个委托仅由一个CLR方法使用,或者定义一种简单的方法来指定所需的委托类型。