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#版本中,您可以声明一个Func
或Action
并获得类似的内容:
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。 所以, angle
variables可以在angledWidth()
函数中访问。
如果你想要返回void
可调用逻辑,你可以用同样的方法使用Action<T>
。 .NET定义了接受N个参数的Funcgenerics,所以你可以使它们变得非常复杂。 一个Func就像一个VB函数或一个C#方法,返回非void; 一个Action就像一个VB Sub,或者一个返回void的C#方法。
自从问了这个问题已经有五年了,现在C#7已经到来了。
它将包括本地function,显然已经实施。
本地function(build议:#259)[目前在未来的分支机构]
delegate
关键字就是这样做的。
void OuterMethod() { var InnerMethod = delegate() { int PlitschPlatsch = 2; }; int anything = 1; InnerMethod(); }
不要忘记,每个范围, PlitschPlatsch
variables将不能在InnerMethod之外访问。
看看匿名方法 。 我想这就是你要找的。
如果你正在寻找的主要是“隐藏”一个只是“帮手”的方法…另一种select是让你的帮手private
。 这样他们就不会成为你class级公共界面的一部分。
这具有如下优点:如果必要的话可以重新使用帮助器; 但它/他们将不会是调用方法的“内部”。
是的,你可以创build方法里面的方法
void OuterMethod(){ int anything = 1; InnedMethod(); void InnerMethod() { int PlitschPlatsch = 2; }}
这是绝对正确的语法和编译器不会通过任何错误,但内部方法的范围只是在外部方法,你不能从外部方法调用内部方法我已经成功地完成了这项工作。 🙂