C #: ¿Función en función posible?

¿Es posible declarar un método dentro de otro método en C #?

Por ejemplo así:

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

Actualización: Las funciones locales se agregaron en la versión 7 C #.

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

En la versión anterior C # tienes que usar una acción como esta:

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

ACTUALIZACIÓN: C # 7 agregó funciones locales ( 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 } } 

En las versiones de C # antes de C # 7, puede declarar un Func o Action y obtener algo similar:

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

si, hay formas Con C # 3.0 tienes el tipo Func que hace esto.

Por ejemplo, escribí esto ayer:

  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 angledWidth = new Func( (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); 

El propósito era agregar una marca de agua a una imagen existente. Quería hacer que el tamaño del texto de la marca de agua fuera del 85% del ancho de la imagen. Pero quería recortar el texto de la marca de agua para que estuviera escrito en un ángulo. Esto reveló la necesidad de hacer algunos cálculos de trigonometría basados ​​en los angularjs, y quería una pequeña función para realizar ese trabajo. El Func es perfecto para eso.

El código anterior define un Func (una función) que acepta un SizeF y devuelve un double , para el ancho real del texto cuando se dibuja en el ángulo dado. Esta función es una variable dentro de una función, y la variable en sí misma contiene una función (referencia a). Entonces puedo invocar esa función "privada" dentro del scope donde la he definido. El Func tiene acceso a las otras variables que se definen antes, en su ámbito de ejecución. Por lo tanto, la variable de angle es accesible dentro de la función angledWidth() .


Si desea una lógica invocable que devuelva el void , puede usar la Action de la misma manera. .NET define los generics funcionales que aceptan N argumentos, por lo que puede hacerlos bastante complicados. Un Func es como una función VB o un método C # que devuelve non-void; una acción es como un VB Sub o un método C # que devuelve vacío.

Han pasado cinco años desde que se hizo esta pregunta y ahora viene C # 7.

Está progtwigdo para incluir funciones locales, y aparentemente ya está implementado.

Funciones locales (Propuesta: # 259) [actualmente en sucursal futura]

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

La palabra clave delegate hace precisamente eso.

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

No olvide que, por scope, la variable PlitschPlatsch no será accesible fuera de InnerMethod.

Echa un vistazo a los métodos anónimos . Creo que eso es lo que estás buscando.

Si está buscando principalmente “ocultar” un método que es solo un “ayudante” … otra opción es hacer que sus ayudantes sean private . De esa manera no se convierten en parte de la interfaz pública de tu clase.

Esto tiene la ventaja de que los ayudantes pueden reutilizarse si es necesario; pero no serán “internos” al método de llamada.