Метод в методе - PullRequest
       2

Метод в методе

52 голосов
/ 15 ноября 2011

Я создаю библиотеку C # с некоторым повторно используемым кодом и пытаюсь создать метод внутри метода.У меня есть такой метод:

public static void Method1()
{
   // Code
}

Я бы хотел сделать следующее:

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

Тогда я мог бы выбрать либо Method1.Method2, либо Method1.Method3.Очевидно, что компилятор не рад этому, любая помощь очень ценится.Спасибо.

Ответы [ 10 ]

95 голосов
/ 15 ноября 2011

Если под вложенным методом вы подразумеваете метод, который вызывается только в этом методе (как в 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);
}
48 голосов
/ 15 ноября 2011

Этот ответ был написан до того, как вышел C # 7. С C # 7 вы можете писать локальные методы.

Нет, ты не можешь этого сделать. Вы можете создать вложенный класс:

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

        public static void Method3()
        {
        }
    }
}

Вы бы тогда позвонили:

ContainingClass.NestedClass.Method2();

или

ContainingClass.NestedClass.Method3();

Я не рекомендовал бы это, хотя. Обычно плохая идея иметь открытые вложенные типы.

Можете ли вы рассказать нам больше о том, чего вы пытаетесь достичь? Там может быть лучше подход.

42 голосов
/ 22 августа 2016

Да, когда C# 7.0 выпущено, Локальные функции позволит вам сделать это.Вы сможете иметь метод внутри метода как:

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

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

    return fullName;
}
25 голосов
/ 15 ноября 2011

Вы можете определить делегатов в вашем методе с полным кодом и вызывать их, если хотите.

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

}
8 голосов
/ 13 апреля 2017

Начиная с C # 7.0, вы можете сделать это:

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

     Hi();
 }

Это называется местные функции , это как раз то, что вы искали.

Я взял пример с здесь , но дополнительную информацию можно найти здесь и здесь .

3 голосов
/ 30 ноября 2017

Старый поток, но в 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 голосов
/ 15 ноября 2011

Почему вы не используете классы?

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

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

Теперь вы можете получить доступ к MethodA через

Helper.MethodA();
2 голосов
/ 15 ноября 2011

Ваш почти там

public static void Method1()

должно быть

public static class Method1{}
1 голос
/ 15 ноября 2011

Разве вы не хотите использовать вместо этого вложенный класс?

Тем не менее, вы, похоже, не соблюдаете Принцип единой ответственности , потому что вы хотите, чтобы один метод выполнял больше, чем одно за один раз.

0 голосов
/ 31 мая 2014

Почему бы вам просто не запустить метод в другом

публичный void M1 () { DO STUFF }

публичный void M1 () { DO STUFF М1 (); }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...