Gambiarra
Until C#6 the only way was the use of lambda which is nothing more than a pointer to function (can eventually store captured variables as well), so it is possible to write the body of a function and store in a variable or pass as argument, or still return in the function that has been declared.
Func<string string> transformaMaiuscula = (string str) => str.ToUpper();
transformaMaiuscula("Teste"); //obviamente pode fazer o que quiser
This feature is a syntactic sugar upon delegates
.
It exists since C# 3. In C# 2 there was the syntax of delegate
which is similar to the syntax of lambda, but less convenient. In C# 1 there was a delegate
, but the syntax was so inconvenient that it had to declare the delegate and then declare and define a separate method, that is, nor could it declare within another method.
Func<string string> transformaMaiuscula = delegate(string str) {
return str.ToUpper();
};
Console.WriteLine(transformaMaiuscula(nome));
That one Func<string string>
is a delegate already declared by . NET, for your convenience. In other circumstances also could use a Action
and very possibly a Predicate
. Only the Predicate
existed in C# 2, which was quite limiting, and which required in practice to declare the delegate outside the method.
I won’t even use the C# example because it doesn’t even look like what’s being asked for, but the delegate’s statement would be delegate string transformaMaiuscula(string str)
, then declare the method with the same signature. The declaration goes inside a type, but not inside a method.
Note that using a delegate with syntax of lambda is quite different from using a normal method. You can even simulate this idea, but they have different characteristics. And it’s a tremendous gambit to do this. Even has memory consumption, processing expense and possible loss of reliability in more complex cases if the programmer does not take certain care.
If you need a delegate there is fine, pay the price of using it. It is not the case of the question.
Syntax lambda out of method
C# 6 even allowed the syntax of Amble is used in any method, so when the method is very simple you can declare your body in a simpler way. It now has the syntax of lamba, but not its semantics. It was only possible to use in normal methods of the types.
string transformaMaiuscula(string str) => str.ToUpper();
Not that this helps the question, I put as a curiosity because people take a long time to get used to new features.
Correct solution
Then one might think: will one do what one has nothing else? Well, I would not use one lambda when only a local (nested) function is desired, as the question shows. My solution, and this is the official recommendation, is to simply deconstruct the function. Just create a separate, probably private, static method and call it where you need it.
It only has one drawback, other methods of the class may call it. But it is something manageable and does not generate any other cost.
private static string transformaMaiuscula(string str) => str.ToUpper();
There inside your method simply calls the method transformaMaiuscula()
like any other.
C# 7
In C# 7 it is already possible to use the local function syntax, so it does not pay any price and is not at risk, not even to allow the call of this function by other members of the class.
The syntax is almost the one used by AP:
static void mostraNome(string nome) {
static string transformaMaiuscula(string str) {
return str.ToUpper();
}
Console.WriteLine(transformaMaiuscula(nome));
}
The static
allowed in syntax, it gives more security to avoid improper captures of variables in the larger context.
Note that you can declare the local method after using it. It is not possible to do this with lambda, the statement must come before always.
Simply put, I could use it like this:
static void mostraNome(string nome) {
static string transformaMaiuscula(string str) => str.ToUpper();
Console.WriteLine(transformaMaiuscula(nome));
}
I put in the Github for future reference.
It is possible for me to specify a parameter and a return to the Action?
– gato
Yes, I’ll edit with one more example.
– Leonel Sanches da Silva
I guess you got it all now.
– Leonel Sanches da Silva
Yes, but I’m going to ask another question about
Func<>
.– gato
Okay, make yourself at home :)
– Leonel Sanches da Silva
Just for the record, it already has an approved proposal for C# 7 that works precisely with the idea that the question had, it is called "Nested local Function". https://github.com/dotnet/roslyn/issues/259
– Gabriel Katakura