.net-C#:功能中的功能可能吗?

是否可以在C#中的另一个方法中声明一个方法?

例如这样的:

void OuterMethod()
{
    int anything = 1;
    InnedMethod();
    void InnerMethod()
    {
        int PlitschPlatsch = 2;
    }
}
Non asked 2019-10-07T21:16:24Z
7个解决方案
54 votes

更新:在版本7 C#中添加的本地功能。

void OuterMethod()
{
    int foo = 1;
    InnerMethod();
    void InnerMethod()
    {
        int bar = 2;
        foo += bar
    }
}

在早期版本的C#中,您必须使用以下操作:

void OuterMethod()
{
    int anything = 1;
    Action InnedMethod = () =>
    {
        int PlitschPlatsch = 2;
    };
    InnedMethod();
}
JaredPar answered 2019-10-07T21:16:41Z
40 votes

更新:C#7添加了本地函数([https://docs.microsoft.com/zh-cn/dotnet/articles/csharp/csharp-7#local-functions)]

void OuterMethod()
{
    int foo = 1;

    InnerMethod();

    void InnerMethod()
    {
        int bar = 2;
        foo += bar
    }

}

在C#7之前的C#版本中,可以声明FuncAction并获得类似的内容:

void OuterMethod()
{
    int foo = 1;
    Action InnerMethod = () => 
    {
        int bar = 2;
        foo += bar;
    } ;

    InnerMethod();
}
jeroenh answered 2019-10-07T21:17:12Z
15 votes

是的,有办法。 使用C#3.0,您可以使用Action<T>类型来执行此操作。

例如,我昨天这样写:

  var image = Image.FromFile(_file);
  int height = image.Height;
  int width = image.Width;
  double tan = height*1.00/width;
  double angle = (180.0 * Math.Atan(tan) / Math.PI);
  var bitmap = new System.Drawing.Bitmap(image, width, height);
  var g = System.Drawing.Graphics.FromImage(bitmap);
  int fontsize = 26; // starting guess
  Font font = null;
  System.Drawing.SizeF size;

  Func<SizeF,double> angledWidth = new Func<SizeF,double>( (x) =>
      {
          double z = x.Height * Math.Sin(angle) +
          x.Width * Math.Cos(angle);
          return z;
      });

  // enlarge for width
  do
  {
      fontsize+=2;
      if (font != null) font.Dispose();
      font = new Font("Arial", fontsize, System.Drawing.FontStyle.Bold);
      size = g.MeasureString(_text, font);
  }
  while (angledWidth(size)/0.85 < width);

目的是在现有图像上添加水印。 我想使水印文本的大小大约为图像宽度的85%。 但是我想倾斜水印文本,以便将它写成一个角度。 这表明需要根据角度进行一些触发计算,而我想要一个小功能来执行该工作。 Action<T>非常适合这样做。

上面的代码定义了一个Action<T>(一个函数),该函数接受SizeF,并返回double,以指定角度绘制文本时的实际宽度。 Func是函数内的变量,并且变量本身包含一个(对a的引用)函数。 然后,我可以在定义它的范围内调用该“私有”函数。 Func可以在其执行范围内访问在其之前定义的其他变量。 因此,可以在angledWidth()函数中访问angle变量。


如果要返回Action<T>608的可调用逻辑,则可以以相同的方式使用Action<T>。 .NET定义了接受N个参数的Func泛型,因此您可以使其变得非常复杂。 Func就像VB函数或C#方法一样,它返回非空值。 一个Action就像一个VB Sub或返回void的C#方法。

Cheeso answered 2019-10-07T21:18:07Z
9 votes

自问这个问题以来已经过去了五年,现在C#7即将问世。

它计划包括本地功能,并且显然已经实现。

局部函数(建议:#259)[当前在将来的分支中]

[https://github.com/dotnet/roslyn/issues/259]

dss539 answered 2019-10-07T21:18:51Z
3 votes

PlitschPlatsch关键字就是这样做的。

void OuterMethod()
{
    var InnerMethod = delegate()
    {
        int PlitschPlatsch = 2;
    };

    int anything = 1;
    InnerMethod();
}

不要忘记,根据作用域,将无法从InnerMethod外部访问PlitschPlatsch变量。

zneak answered 2019-10-07T21:19:23Z
1 votes

看一下匿名方法。 我认为这就是您要寻找的。

T.K. answered 2019-10-07T21:19:48Z
0 votes

如果您主要希望“隐藏”仅是“帮助程序”的方法,则另一种选择是使您的帮助程序private。这样,它们就不会成为您班级公共接口的一部分。

这样做的好处是,如果需要,可以重新使用帮助程序。 但它/它们不会是调用方法的“内部”。

David answered 2019-10-07T21:20:21Z
translate from https://stackoverflow.com:/questions/5884319/c-function-in-function-possible