C#:函数中的函数可能吗?

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

例如那样:

void OuterMethod() { int anything = 1; InnedMethod(); void InnerMethod() { int PlitschPlatsch = 2; } } 

不直接没有。 C#不支持内部方法。 它确实支持匿名方法,尽pipe它们可以用于相同的目的

 void OuterMethod() { int anything = 1; Action InnedMethod = () => { int PlitschPlatsch = 2; }; InnedMethod(); } 

更新:C#7添加本地function( https://docs.microsoft.com/en-us/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(); } 

是的,有办法。 在C#3.0中,你有这样的Func<T>types。

例如,我昨天写了这个:

  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%。 但是我想把水印文字弄错,所以写在一个angular度上。 这揭示了需要做一些基于angular度的trig计算,我想要一个小function来执行这个工作。 Func是完美的。

上面的代码定义了一个Func (一个函数),该函数接受一个SizeF并返回一个double ,对于以给定angular度绘制的文本的实际宽度。 这个Func是一个函数内的一个variables,variables本身包含一个(引用一个)函数。 然后我可以在我定义的范围内调用这个“private”函数。 Func可以访问在其执行范围内定义的其他variables。 所以, anglevariables可以在angledWidth()函数中访问。


如果你想要返回void可调用逻辑,你可以用同样的方法使用Action<T> 。 .NET定义了接受N个参数的Funcgenerics,所以你可以使它们变得非常复杂。 一个Func就像一个VB函数或一个C#方法,返回非void; 一个Action就像一个VB Sub,或者一个返回void的C#方法。

自从问了这个问题已经有五年了,现在C#7已经到来了。

它将包括本地function,显然已经实施。

本地function(build议:#259)[目前在未来的分支机构]

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

delegate关键字就是这样做的。

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

不要忘记,每个范围, PlitschPlatschvariables将不能在InnerMethod之外访问。

看看匿名方法 。 我想这就是你要找的。

如果你正在寻找的主要是“隐藏”一个只是“帮手”的方法…另一种select是让你的帮手private 。 这样他们就不会成为你class级公共界面的一部分。

这具有如下优点:如果必要的话可以重新使用帮助器; 但它/他们将不会是调用方法的“内部”。

是的,你可以创build方法里面的方法

 void OuterMethod(){ int anything = 1; InnedMethod(); void InnerMethod() { int PlitschPlatsch = 2; }} 

这是绝对正确的语法和编译器不会通过任何错误,但内部方法的范围只是在外部方法,你不能从外部方法调用内部方法我已经成功地完成了这项工作。 🙂