Estoy usando Linq To XML
new XElement("Prefix", Prefix == null ? "" : Prefix)
pero quiero hacer algunos cálculos con el prefijo antes de agregarlo al xml, como eliminar espacios, caracteres especiales, algunos cálculos, etc.
No quiero crear funciones porque estas no serán de ninguna ayuda en ninguna otra parte de mi programa, pero esto, ¿hay alguna forma de crear funciones en línea?
Respuestas:
Sí, C # lo admite. Hay varias sintaxis disponibles.
Se agregaron métodos anónimos en C # 2.0:
Func<int, int, int> add = delegate(int x, int y) { return x + y; }; Action<int> print = delegate(int x) { Console.WriteLine(x); } Action<int> helloWorld = delegate // parameters can be elided if ignored { Console.WriteLine("Hello world!"); }
Las lambdas son nuevas en C # 3.0 y vienen en dos sabores.
Lambdas de expresión:
Func<int, int, int> add = (int x, int y) => x + y; // or... Func<int, int, int> add = (x, y) => x + y; // types are inferred by the compiler
Lambdas de declaración:
Action<int> print = (int x) => { Console.WriteLine(x); }; Action<int> print = x => { Console.WriteLine(x); }; // inferred types Func<int, int, int> add = (x, y) => { return x + y; };
Las funciones locales se han introducido con C # 7.0:
int add(int x, int y) => x + y; void print(int x) { Console.WriteLine(x); }
Básicamente, existen dos tipos diferentes de estos:
Func
yAction
.Func
s devuelven valores peroAction
no. El último parámetro de tipo de aFunc
es el tipo de retorno; todos los demás son tipos de parámetros.Hay tipos similares con diferentes nombres, pero la sintaxis para declararlos en línea es la misma. Un ejemplo de esto es
Comparison<T>
, que es aproximadamente equivalente aFunc<T, T, int>
.Func<string, string, int> compare1 = (l,r) => 1; Comparison<string> compare2 = (l, r) => 1; Comparison<string> compare3 = compare1; // this one only works from C# 4.0 onwards
Estos se pueden invocar directamente como si fueran métodos regulares:
int x = add(23, 17); // x == 40 print(x); // outputs 40 helloWorld(x); // helloWorld has one int parameter declared: Action<int> // even though it does not make any use of it.
fuente
C # 7 agrega soporte para funciones locales
Aquí está el ejemplo anterior usando una función local
void Method() { string localFunction(string source) { // add your functionality here return source ; }; // call the inline function localFunction("prefix"); }
fuente
La respuesta a su pregunta es sí y no, dependiendo de lo que quiera decir con "función en línea". Si está usando el término como se usa en el desarrollo de C ++, entonces la respuesta es no, no puede hacer eso, incluso una expresión lambda es una llamada a función. Si bien es cierto que puede definir expresiones lambda en línea para reemplazar declaraciones de funciones en C #, el compilador aún termina creando una función anónima.
Aquí hay un código realmente simple que usé para probar esto (VS2015):
static void Main(string[] args) { Func<int, int> incr = a => a + 1; Console.WriteLine($"P1 = {incr(5)}"); }
¿Qué genera el compilador? Usé una ingeniosa herramienta llamada ILSpy que muestra el ensamblaje de IL real generado. Eche un vistazo (he omitido muchas cosas de configuración de clases)
Esta es la función principal:
IL_001f: stloc.0 IL_0020: ldstr "P1 = {0}" IL_0025: ldloc.0 IL_0026: ldc.i4.5 IL_0027: callvirt instance !1 class [mscorlib]System.Func`2<int32, int32>::Invoke(!0) IL_002c: box [mscorlib]System.Int32 IL_0031: call string [mscorlib]System.String::Format(string, object) IL_0036: call void [mscorlib]System.Console::WriteLine(string) IL_003b: ret
¿Ves esas líneas IL_0026 e IL_0027? Esas dos instrucciones cargan el número 5 y llaman a una función. Luego, formatee IL_0031 e IL_0036 e imprima el resultado.
Y aquí está la función llamada:
.method assembly hidebysig instance int32 '<Main>b__0_0' ( int32 a ) cil managed { // Method begins at RVA 0x20ac // Code size 4 (0x4) .maxstack 8 IL_0000: ldarg.1 IL_0001: ldc.i4.1 IL_0002: add IL_0003: ret } // end of method '<>c'::'<Main>b__0_0'
Es una función realmente corta, pero es una función.
¿Vale la pena hacer algún esfuerzo para optimizarlo? Nah. Tal vez si lo llama miles de veces por segundo, pero si el rendimiento es tan importante, entonces debería considerar llamar al código nativo escrito en C / C ++ para que haga el trabajo.
En mi experiencia, la legibilidad y la capacidad de mantenimiento son casi siempre más importantes que la optimización para obtener unos pocos microsegundos de ganancia de velocidad. Utilice funciones para hacer que su código sea legible y para controlar el alcance de las variables y no se preocupe por el rendimiento.
"La optimización prematura es la raíz de todos los males (o al menos la mayor parte) en la programación". - Donald Knuth
"Un programa que no se ejecuta correctamente no necesita ejecutarse rápido" - Yo
fuente
Si.
Puede crear métodos anónimos o expresiones lambda :
Func<string, string> PrefixTrimmer = delegate(string x) { return x ?? ""; }; Func<string, string> PrefixTrimmer = x => x ?? "";
fuente
code
Func <string, string> PrefixTrimmer = x => x? "";code
Soy nuevo en esto y realmente no entiendo muy bien el documento de MSDNx ?? ""
es el operador de fusión nula. msdn.microsoft.com/en-us/library/ms173224.aspxx => (something)
,x
es un parámetro y(something)
es el valor de retorno`.Puede usar Func, que encapsula un método que tiene un parámetro y devuelve un valor del tipo especificado por el parámetro TResult.
void Method() { Func<string,string> inlineFunction = source => { // add your functionality here return source ; }; // call the inline function inlineFunction("prefix"); }
fuente
No solo los métodos Inside, también se pueden usar dentro de las clases.
class Calculator { public static int Sum(int x,int y) => x + y; public static Func<int, int, int> Add = (x, y) => x + y; public static Action<int,int> DisplaySum = (x, y) => Console.WriteLine(x + y); }
fuente