web-dev-qa-db-ja.com

メソッド内のメソッド

再利用可能なコードを使用してC#ライブラリを作成していますが、メソッド内にメソッドを作成しようとしました。私はこのような方法があります:

public static void Method1()
{
   // Code
}

私がやりたいのはこれです:

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

次に、Method1.Method2またはMethod1.Method3。明らかに、コンパイラはこれについて満足していません。どんな助けも大歓迎です。ありがとう。

53
Bali C

この回答は、C#7が登場する前に書かれました。C#7を使用すると、canローカルメソッドを記述できます。

いいえ、できません。あなたはcouldネストされたクラスを作成します:

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

        public static void Method3()
        {
        }
    }
}

次に電話します:

ContainingClass.NestedClass.Method2();

または

ContainingClass.NestedClass.Method3();

はこれを推奨しません通常入れ子になった型をパブリックにするのは悪い考えです。

達成しようとしていることについて詳しく教えてください。より良いアプローチがあるかもしれません。

48
Jon Skeet

ネストされたメソッドとは、そのメソッド内でのみ呼び出し可能なメソッドを意味する場合(Delphiなど)、デリゲートを使用できます。

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

はい、C# 7.0がリリースされました。 Local Functions を使用すると、それが可能になります。次のようにメソッド内にメソッドを持つことができます。

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

完全なコードを使用してメソッド内でデリゲートを定義し、必要に応じて呼び出すことができます。

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);

   }
}

次のように、外部からは見えないクラス内でネストされたクラスを使用し、そのメソッドを呼び出す代替手段が常にあります。

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

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

}
25

C#7.0以降、次のことができます。

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

     Hi();
 }

これはlocal funtionsと呼ばれ、まさにあなたが探していたものです。

here から例を取り上げましたが、さらに情報を見つけることができます here および here

8
Luis Teijon

古いスレッドですが、C#にはネストされた関数の概念があります

    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

なぜクラスを使用しないのですか?

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

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

これでMethod vivaにアクセスできます

Helper.MethodA();
3
masterchris_99

あなたのほとんどそこに

public static void Method1()

あるべき

public static class Method1{}
2
Ash Burlaczenko

代わりに、ネストされたクラスを使用しませんか?

つまり、単一のメソッドが一度に複数のことを行うようにするため、 単一責任原則 を尊重しないようです。

1
JiBéDoublevé