Function within another

Asked

Viewed 1,247 times

6

In Javascript, I can structure my code well by placing auxiliary functions inside other functions. For example:

I get something similar in C#? If not, how do you not leave the auxiliary functions "loose" in the project?

function Salva() {
    if(valida()) insereNoBanco();

    function valida() {
        // valida campos
    }

    function insereNoBanco() {
        // insere dados no banco
    }
}
  • Good question, but it had some different interpretations, I suggest you read the answers carefully.

  • This Bruno, read carefully the answers and accept to which really responds well what you asked. If you still don’t know what acceptance is like, check out the [tour].

4 answers

8

In C# this was not possible (has in C# 7, see more in another question here). Enough to create delegates, but I doubt it’s what you want.

As a matter of fact, I see little use for it. Normally this will only be necessary if the code is too large and yet, the solution is not to create Inner functions, as shown in Javascript. This is done in JS because it is a language that has limitations to limit visibility and scope.

The idea of structuring parts of the code into separate functions is good, it separates responsibilities, but it doesn’t have to be within. Create other functions outside of it. The only drawback of this is that externally any other method in the class can call it. If it were internal, only it could call the function. But this is not usually a problem.

Of course you should create this function/method, such as private so it can’t be accessed outside the class.

public void Salva() => if (valida()) insereNoBanco();
private bool valida() {
    // valida campos
}
private void insereNoBanco() {
    // insere dados no banco
}

I wouldn’t do this but Daniel’s response put an example of what I initially said in the answer about lambda and which is the closest to the simulation of Inner fucntion used in Javascript:

public void Salva() {
    Func<bool> valida = () => {
        // valida campos
    };

    Action insereNoBanco = () => {
        // insere dados no banco
    };
    if (valida()) insereNoBanco();
}

I put in the Github for future reference.

It is unnecessary to do this, can have unwanted effects and is not idiomatic in C#.

  • As I understood from his question, he did not let the auxiliary methods be in the same class "file"

  • At no time does he show it. You seem to have assumed it. And in your answer it seems like you assumed that everyone understands what you’re saying, what you’re supposed to do. The way I understand it, you can’t do what you suggest in every situation. If these functions access private members of the class instance, it cannot be static, much less another class. And there is a good chance of this occurring, after all in his example, the auxiliary function was very internal and the names indicate that it will do something that depends on other existing values.

  • If not, how do you not leave the auxiliary functions "loose" in the project? Soltas for me it means that the functions are auxiliares are not part of the scope of a class, ie can be used in many places and that he does not want to implement again the methods in all classes, he does not want to leave perdido their methods

  • But then it can be used in any part of the project, it’s not what he did in his example. He does not want to let go of everything, he is released from the function he will use. He has to read the context. He cannot read only the sentence of the question. In the example the function is internal precisely not to use in other parts of the project. You probably do not understand the concept of Inner fucntion. Just as you had posted an example that did not simulate multiple inheritance, did something else, now, you are doing something else, and not simulating a Inner fucntion.

6


In Javascript a function creates its own scope, and subfunctions inherit scopes.

In C#, scopes are defined by blocks (classes or methods), and are inherited by internal classes only.

An expression similar to his example would be the following:

internal static class Mae
{
    private static bool PodeSalvar = true;

    internal static void Salva()
    {

        Console.WriteLine(Filha.FilhaSalva); //Erro: Fora de escopo

        if (Filha.Valida()) Filha.InsereNoBanco();
    }

    internal static class Filha
    {
        private static bool FilhaSalva = false;

        internal static bool Valida()
        {
            return PodeSalvar; // Funciona, pois Filha herda o escopo de Mae
        }

        internal static void InsereNoBanco()
        {
            // insere dados no banco
        }
    }
}

Note that PodeSalvar is defined in the class Mae, and the method Valida() inner-class Filha has access to it, even if it has been defined as Private.

Meanwhile, FilhaSalva cannot be read by methods in the class Mae, even with a full descriptor (Filha.FilhaSalva) - since FilhaSalva is defined as Private.

  • +1 because it is correct and is nevertheless an alternative in a specific case. It’s too complex a solution for ordinary cases and I think even you agree.

  • @bigown to tell the truth, yes, I agree - but subclass is the only case of access scope that occurred to me that had not yet been discussed.

  • Although the terms there are confusing. I no longer liked the names of the classes because it leads me to believe that this is an inheritance, which anyone who knows the language sees that it is not. All right. Now you spoke in subclass, It refers again to inheritance, which it is not. This is a Inner class (inner class? ). This does not change the answer, just to be clear.

  • @bigown you’re right, the correct term is inner class. Thanks for the tip, I’ve adjusted the answer.

  • He liked his complex solution :D It doesn’t seem to be what he actually wants but each one with his head

  • It’s the right answer because it concisely addresses the scope of C functions#.

Show 1 more comment

5

You can declare functions within a method using lambda expressions:

Func<int, string> convertIntParaString = (num1) => num1.ToString();

Action<string, int> doisParamsSemRetorno = (str1, num1) =>
{
    str1.ToUpper();
    num1.ToString();
};

Using your code as an example:

void Salva() 
{
    Func<bool> valida = () => 
    {
        // valida campos
        return true;
    };

    Action insereNoBanco = () =>
    {
        // insere dados no banco
    };

    if(valida())
        insereNoBanco();
}
  • 1

    Creative response, was even copied by another answer ;-)

1

Ideal would be for you to create a support class containing the methods you need. So your code is more organized and easy to maintain. Below is a very simple example.

namespace Exemple
{
    public class Suporte
    {
        public static void Mensagem()
        {
            MessageBox.Show("Este é um método de apoio");
        }
    }
}

namespace Exemple
{
    public class Principal
    {
        public void ExibeMensagem()
        {
           Suporte.Mensagem();
        }
    }
}
  • 1

    Generally speaking there is no need to create an auxiliary class. You may have it in some specific situation. But for functions that would be within the function, it would be an exaggeration to create an auxiliary class. Anyway, if it were a case where this is interesting, it’s not the focus of the question.

  • @bigown looks like Voce is the only one with different opinion.

  • This answer is falling into the same mistake, it does something other than what is in the question. So much so that, just to illustrate, her example and the other wrong answer show operations totally different from the example of the question. My answer shows how to solve the AP problem and Daniel’s answer shows how to simulate the same resource in a way that is close to that of JS but not idiomatic in C#. This response also prevents access by private members of the class instance in question.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.