web-dev-qa-db-fra.com

Méthode dans une méthode

Je crée une bibliothèque C # avec du code réutilisable et essayais de créer une méthode à l'intérieur d'une méthode. J'ai une méthode comme celle-ci:

public static void Method1()
{
   // Code
}

Ce que je voudrais faire, c'est ceci:

public static void Method1()
{
   public static void Method2()
   {
   }
   public static void Method3()
   {
   }
}

Ensuite, je pourrais choisir soit Method1.Method2 ou Method1.Method3. Évidemment, le compilateur n'est pas content de cela, toute aide est très appréciée. Merci.

53
Bali C

Cette réponse a été écrite avant la sortie de C # 7. Avec C # 7 vous pouvez écrire des méthodes locales.

Non, tu ne peux pas faire ça. Vous pourriez créer une classe imbriquée:

public class ContainingClass
{
    public static class NestedClass
    {
        public static void Method2()
        {
        } 

        public static void Method3()
        {
        }
    }
}

Vous appelleriez alors:

ContainingClass.NestedClass.Method2();

ou

ContainingClass.NestedClass.Method3();

Je ne le recommanderais pas . Habituellement c'est une mauvaise idée d'avoir des types imbriqués publics.

Pouvez-vous nous en dire plus sur ce que vous essayez de réaliser? Il pourrait bien y avoir une meilleure approche.

48
Jon Skeet

Si par méthode imbriquée, vous voulez dire une méthode qui ne peut être appelée que dans cette méthode (comme dans Delphi), vous pouvez utiliser des délégués.

public static void Method1()
{
   var method2 = new Action(() => { /* action body */ } );
   var method3 = new Action(() => { /* action body */ } );

   //call them like normal methods
   method2();
   method3();

   //if you want an argument
   var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
   actionWithArgument(5);

   //if you want to return something
   var function = new Func<int, int>(i => { return i++; });
   int test = function(6);
}
95
Ray

Oui quand C# 7.0 est libéré, Fonctions locales vous permettra de le faire. Vous pourrez avoir une méthode, à l'intérieur d'une méthode comme:

public int GetName(int userId)
{
    int GetFamilyName(int id)
    {
        return User.FamilyName;
    }

    string firstName = User.FirstName;
    var fullName = firstName + GetFamilyName(userId);

    return fullName;
}
42
Zeeshan

Vous pouvez définir des délégués dans votre méthode avec un code complet et les appeler si vous le souhaitez.

public class MyMethods
{
   public void Method1()
   {
     // defining your methods 

     Action method1 = new Action( () => 
      { 
         Console.WriteLine("I am method 1");
         Thread.Sleep(100);
         var b = 3.14;
         Console.WriteLine(b);
      }
     ); 

     Action<int> method2 = new Action<int>( a => 
      { 
         Console.WriteLine("I am method 2");
         Console.WriteLine(a);
      }
     ); 

     Func<int, bool> method3 = new Func<int, bool>( a => 
      { 
         Console.WriteLine("I am a function");
         return a > 10;
      }
     ); 


     // calling your methods

     method1.Invoke();
     method2.Invoke(10);
     method3.Invoke(5);

   }
}

Il y a toujours une alternative d'utiliser une classe imbriquée dans une classe qui ne sera pas visible de l'extérieur et d'appeler ses méthodes, comme:

public class SuperClass
{
    internal static class HelperClass
    {
      internal static void Method2() {}
    }

    public void Method1 ()
    {
      HelperClass.Method2();
    }

}
25
Alexander Galkin

Depuis C # 7.0, vous pouvez le faire:

 public static void SlimShady()
 {
     void Hi([CallerMemberName] string name = null)
     {
         Console.WriteLine($"Hi! My name is {name}");
     }

     Hi();
 }

C'est ce qu'on appelle les fonctions locales , c'est exactement ce que vous cherchiez.

J'ai pris l'exemple de ici , mais d'autres informations peuvent être trouvées ici et ici .

8
Luis Teijon

Fil plus ancien, mais C # a le concept de fonctions imbriquées

    Func<int> getCalcFunction(int total, bool useAddition)
    {
        int overallValue = 0;
        if (useAddition)
        {
            Func<int> incrementer = new Func<int>(() =>
            {
                overallValue += total;
                return overallValue;
            });
            return incrementer;
        }
        else
        {
            Func<int> decrementer = new Func<int>(() =>
            {
                overallValue -= total;
                return overallValue;
            });
            return decrementer;
        }
    }
    private void CalcTotals()
    {
        Func<int> decrem = getCalcFunction(30, false);
        int a = decrem(); //result = -30
        a = decrem(); //result = -60

        Func<int> increm = getCalcFunction(30, true);
        int b = increm(); //result = 30
        b = increm(); //result = 60
    }
3
oldSchool

Pourquoi vous n'utilisez pas de cours?

public static class Helper
    {
        public static string MethodA()
        {
            return "A";
        }

        public static string MethodA()
        {
            return "A";
        }
    }

Vous pouvez maintenant accéder à Method via

Helper.MethodA();
3
masterchris_99

Vous y êtes presque

public static void Method1()

devrait être

public static class Method1{}
2
Ash Burlaczenko

Vous ne souhaitez pas utiliser la classe imbriquée à la place?

Cela dit, vous semblez ne pas respecter le principe de responsabilité unique parce que vous voulez qu'une seule méthode fasse plus d'une chose à la fois.

1
JiBéDoublevé