【问题标题】:Can a C# method return a method?C#方法可以返回一个方法吗?
【发布时间】:2011-09-27 15:41:45
【问题描述】:

C# 中的方法可以返回方法吗?

例如,一个方法可以返回一个lambda expression,但我不知道我可以给这样一个方法什么样的类型参数,因为一个方法不是Type。这样一个返回的方法可以分配给某个委托。

以这个概念为例:

public <unknown type> QuadraticFunctionMaker(float a , float b , float c)
{
    return (x) => { return a * x * x  + b * x + c; };
}

delegate float Function(float x);
Function QuadraticFunction = QuadraticFunctionMaker(1f,4f,3f);

【问题讨论】:

  • 您已经声明了必要的委托类型。您的问题到底是什么?

标签: c# methods lambda return-type


【解决方案1】:

您要查找的类型是Action&lt;&gt;Func&lt;&gt;

这两种类型的泛型参数决定了方法的类型签名。如果您的方法没有返回值,请使用Action。如果它有返回值,请使用Func,其中最后一个泛型参数是返回类型。

例如:

public void DoSomething()                          // Action
public void DoSomething(int number)                // Action<int>
public void DoSomething(int number, string text)   // Action<int,string>

public int DoSomething()                           // Func<int>
public int DoSomething(float number)               // Func<float,int>
public int DoSomething(float number, string text)  // Func<float,string,int>

【讨论】:

    【解决方案2】:

    您可以使用dynamic 关键字。请参阅dynamic (C# Reference)

    【讨论】:

    • 这是最糟糕的选择。
    • 动态键,它所做的只是跳过编译时类型检查,使用这个关键字将是一个hack而不是解决方案
    【解决方案3】:

    您的 lambda 表达式将采用 float 作为参数(我相信),然后也返回 float。在.NET 中,我们可以用Func&lt;float, float&gt; 类型来表示它。

    一般来说,如果您要处理带有更多参数的 lambda,您可以使用 Func&lt;Type1, Type2, Type3, ..., ReturnType&gt;,最多带有八个参数。

    【讨论】:

      【解决方案4】:

      &lt;unknown type&gt; = Function。也就是说,

      public Function QuadraticFunctionMaker(float a , float b , float c)
      {
          return (x) => { return a * x * x  + b * x + c; };
      }
      

      这是您要查找的内容,因为您已经声明了要匹配的委托 Function。或者,您根本不需要声明委托,可以使用Func&lt;float, Float&gt;,正如其他人所注意到的那样。这是完全等价的。事实上,Func&lt;T, T&gt; 的声明方式与您的委托 Function 完全相同,只是它是泛型的。

      【讨论】:

      • 最好使用Func&lt;&gt;Action&lt;&gt; 之类的东西。我相信 MS 正在摆脱到处都有自定义代表。
      • @siride:不,不是。当你想让你的意图明确时,一个强定义的委托会更好
      • @JeffN825:问题是您不能在没有明确期望这种委托的上下文中轻松地传递自定义委托。如果 .NET 能够具有委托层次结构或特征或一些模糊有用的东西,我会同意你的看法。否则,使用除通用版本之外的任何东西都会很痛苦。
      • 当然可以,只要签名匹配。如果你问我,传递一个带有六个参数的 Action 简单地命名为 p1 到 p6 会让人很困惑。
      • @JeffN825:我同意,但这只是因为 .NET 中的委托系统很烂。但是,由于具有相同参数和返回类型的委托之间不必要的不​​兼容,与其通过命名的委托增加一点并使生活更加复杂,而不是让它变得更糟。
      【解决方案5】:
      public Func<float, float> QuadraticFunctionMake(float a, float b, float c) {
          return x => a * x * x + b * x + c;
      }
      

      返回类型为Func&lt;float, float&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-15
        • 2016-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多