En C# 8.0, se anuncian funciones locales estáticas
¿Alguien puede ayudarme a aclararme por qué querría declarar una función local como estática?
La razón dada en el artículo:
para garantizar que la función local no capture (haga referencia) a ninguna variable del ámbito adjunto
Pero:
El código de ejemplo dado en el artículo es:
int M() { int y = 5; int x = 7; return Add(x, y); static int Add(int left, int right) => left + right; }No entiendo por qué querrías asegurar eso.
Porque evita que te dispares en el pie. Obliga a la función local a ser una función pura que no modifica el estado de la persona que llama.
Esto devuelve false , porque la función modifica las variables locales de su llamador:
public bool Is42() { int i = 42; Foo(); return i == 42; void Foo() { i = 21; } }Y esto no, porque ni siquiera compila:
public bool Is42() { int i = 42; Foo(); return i == 42; static void Foo() { i = 21; } } Evita sorpresas. Por supuesto, en estos ejemplos simples, el beneficio no es claro de inmediato, porque "bueno, es obvio que Foo() modifica i " , pero en bases de código más grandes mantenidas por varias personas y no cubiertas adecuadamente por pruebas unitarias, este simple modificador evita problemas.
La captura de variables tiene un pequeño costo adicional, ya que generará un tipo de uso interno en el que las variables capturadas son campos públicos. Considere un ejemplo ligeramente modificado:
int M() { int y = 5; int x = 7; return Add(); int Add() => x + y; }En realidad se traducirá a algo como esto:
int M() { int y = 5; int x = 7; var capturedVars = new <>c__DisplayClass0_0 { x = x, y = y }; return <M>g__Add|0_0(ref capturedVars); } [CompilerGenerated] private struct <>c__DisplayClass0_0 { public int x; public int y; } [CompilerGenerated] internal static int <M>g__Add|0_0(ref <>c__DisplayClass0_0 class_Ref1) => (class_Ref1.x + class_Ref1.y);Esta respuesta de CodeCaster y esta respuesta separada de György Kőszeg responden individualmente diferentes partes de mi pregunta, por lo que las estoy reuniendo para formar una imagen completa de la respuesta aceptada:
Para la Parte 1) de mi pregunta, @CodeCaster dice:
Porque evita que te dispares en el pie. Obliga a la función local a ser una función pura que no modifica el estado de la persona que llama .
en bases de código más grandes mantenidas por varias personas y no cubiertas adecuadamente por pruebas unitarias, este simple modificador evita problemas
Entonces, la respuesta 1 es: las funciones locales estáticas garantizan un estado confiable del método de la persona que llama.
Para la Parte 2) de mi pregunta, @György Kőszeg dice:
La captura de variables tiene un pequeño costo adicional, ya que generará un tipo de uso interno en el que las variables capturadas son campos públicos.
Y continúa dando un ejemplo del código compilador producido a través de reflector.
Entonces, la respuesta 2 es: las funciones locales estáticas evitan la captura de variables. La captura de variables tiene un costo pequeño. Por lo tanto, hay un pequeño aumento de rendimiento al declarar la función local estática