Function within another

6

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

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

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

    function valida() {
        // valida campos
    }

    function insereNoBanco() {
        // insere dados no banco
    }
}
    
asked by anonymous 29.09.2015 / 16:54

4 answers

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 your example would be as follows:

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 class Mae , and the Valida() method of inner class Filha has access to it, even though it has been set to Private .

However, FilhaSalva can not be read by methods in class Mae , even with a complete descriptor ( Filha.FilhaSalva ) - since FilhaSalva is set to Private .     

29.09.2015 / 19:36
8

In C # this is not possible, at least not at the moment ( has in C # 7 , see more at another question qui ). You could create delegates , but I doubt it's what you want.

To tell you the truth, I see little use for this. Usually this will only be necessary if the code is too large and 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, separates responsibilities, but does not need to be within another. Create other functions outside of it. The only disadvantage of this is that externally any other method of the class can call it. If it were internal, only she 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 not be accessed outside the class.

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

I would not do this but Daniel's answer put an example of what I initially said in the lambda answer and that is closest to the inner fucntion simulation used in JavaScript:

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

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

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

    
29.09.2015 / 17:03
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();
}
    
29.09.2015 / 17:52
1

The ideal would be for you to create a support class containing the methods you need. So your code gets 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();
        }
    }
}
    
29.09.2015 / 17:39