【问题标题】:Is there anything that you can do with 'delegate' but cannot do with either 'Action' or 'Func'?有什么你可以用“delegate”做但不能用“Action”或“Func”做的事情吗?
【发布时间】:2014-06-04 16:48:45
【问题描述】:

提前为 新手 有点问题道歉(因为我是 C# 中的一员):

在研究代表时,在我看来ActionFunc 的组合涵盖了delegate 关键字的全部“功能”。

换句话说,你不能用delegate 关键字做任何事情,但不能用ActionFunc 做任何事情。

我尝试了以下示例(效果很好):

Func<int,int,int,int> func = (x,y,z) => (x<<9)|(y<<6)|(z<<3);
Action<int,int,int> action = (x,y,z) => Console.WriteLine(x|y|z);

我错了吗?如果是的话,请您提供一个反例吗?

【问题讨论】:

  • 我会定义 Action 和 Func als Wrapper/helper 类,使程序易于使用和标准化的委托。
  • 谢谢@Tarec。我希望我的问题与以前的一些帖子重复,但一直没能找到。您的链接为我的问题提供了部分答案,但它解释了我已经知道的一些事情。所以基本上我只是想弄清楚一旦你有ActionFunc它“涵盖了整个事情”,还是我在这里遗漏了什么?再次感谢。
  • @barakmanos 你是对的,这个答案并不能解释使用两者的目的的区别。请查看此说明,希望对您有所帮助;)stackoverflow.com/a/18741018/1284902

标签: c# delegates


【解决方案1】:

如果您想拥有,则需要使用 ActionFunc 以外的委托:

  1. 您的方法有超过 16 个参数。

  2. 任何参数都是refout 参数。

  3. params 参数。

  4. 任何参数的可选参数。

  5. 对任何通用参数的约束。 (确保参数是扩展类型的任何类型,它具有无参数构造函数,它是值/引用类型等)

  6. unsafe 方法签名中使用的类型,例如作为参数的指针。

  7. 有一个不是逆变的参数,或者一个不是协变的返回类型。 FuncAction 都尽可能应用变体,因此如果您的委托变体很重要,您将需要自己的。

【讨论】:

  • outparams 和可选参数实际上是Action/Func 的一种常见且更普遍的不可能性的三个结果:指定自定义属性的能力。
  • 您可以添加unsafe 类型的情况,即一些参数或返回值是指针类型的委托类型。例如public unsafe delegate string GetString(char* value);.
  • 如果您不希望将类型参数标记为协变或逆变,则另一种用途。请注意,System.EventHandler&lt;TEventArgs&gt;TEventArgs 中不是逆变的(不是“in”),因为它可能会导致多播委托出现问题。所以在这方面它与Action&lt;object, TEventArgs&gt; 不同。
  • @JeppeStigNielsen 添加。谢谢。
【解决方案2】:

您可以创建采用refout 参数的委托。您不能定义具有refout 参数的FuncAction

例如:

delegate void MyDelegate(ref string val);

不能表示为Action

【讨论】:

    【解决方案3】:

    我的两分钱:使用您自己的通用代表,您可以申请 generic constraints,这是 FuncAction 未提供的

    delegate void MyDelegate<T>(T input) where T : struct;
    

    编译器将确保MyDelegate&lt;T&gt; 的值类型始终为T,不允许引用类型。

    【讨论】:

      猜你喜欢
      • 2011-02-02
      • 1970-01-01
      • 2012-11-17
      • 2020-07-09
      • 1970-01-01
      • 2021-03-02
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多