60

I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:

public static void Method1()
{
   // Code
}

What I would like to do is this:

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

Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.

Bali C
  • 30,582
  • 35
  • 123
  • 152
  • 3
    How would a concept of a method inside a method work in C#? The last time I ever saw nested function/method definitions was in PHP and JavaScript, but those were for creating top-level functions on the fly. – BoltClock Nov 15 '11 at 10:42
  • put the two methods in a static class. – Mubashir Khan Nov 15 '11 at 10:44
  • What do you want to achieve with this? – Abdul Munim Nov 15 '11 at 10:44
  • 7
    Easy, you can only call it from that method. Delphi supports it. – Ray Nov 15 '11 at 10:44
  • @Ray: And you could do *that* via anonymous functions, sort of... but that doesn't tally with "choose either Method1.Method2 or Method1.Method3". – Jon Skeet Nov 15 '11 at 10:48
  • @JonSkeet yes you could (see my answer). But yeah I'm not sure if he means he wants to call them from outside or not. – Ray Nov 15 '11 at 10:49
  • 2
    In Delphi you can do it, but nested methods will be 'private' and only the parent method will be able to access to it. Anyway I miss a lot this delphi/pascal feature to get more clean/organized code. – ferpega Nov 17 '11 at 12:18
  • FWIW, this is a feature of Pascal, not just of Delphi. It makes sense if some tasks must be repeated several times in the same outer method. It is not the same as anonymous methods. – Rudy Velthuis Jul 14 '14 at 03:35
  • possible duplicate of [how to create function inside another function in c#,is it possible?](http://stackoverflow.com/questions/2047200/how-to-create-function-inside-another-function-in-c-is-it-possible) – Ferruccio Jun 03 '15 at 15:40
  • Possible duplicate of [C#: Function in Function possible?](http://stackoverflow.com/questions/5884319/c-function-in-function-possible) – Des Horsley Dec 03 '15 at 05:58

10 Answers10

101

If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.

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);
}
Ray
  • 45,695
  • 27
  • 126
  • 169
60

Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:

public int GetName(int userId)
{
    int GetFamilyName(int id)
    {
        return User.FamilyName;
    }
    
    string firstName = User.FirstName;
    var fullName = firstName + GetFamilyName(userId);

    return fullName;
}

Note that public (and similar modifiers) are not supported C# programming guide:

Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Zeeshan
  • 2,884
  • 3
  • 28
  • 47
  • 1
    that's good to know. is it possible in this example to use the userId value inside the nested GetFamilyName() function without passing it as a parameter? – symbiont Oct 18 '16 at 08:43
  • @symbiont: Yes, the arguments (and local variables) of the main function are visible to the local one (similar to Delphi). See the second exxample in the image in http://www.infoworld.com/article/3182416/application-development/c-7-in-depth-exploring-local-functions.html – John B. Lambe Apr 14 '17 at 12:48
51

This answer was written before C# 7 came out. With C# 7 you can write local methods.

No, you can't do that. You could create a nested class:

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

        public static void Method3()
        {
        }
    }
}

You'd then call:

ContainingClass.NestedClass.Method2();

or

ContainingClass.NestedClass.Method3();

I wouldn't recommend this though. Usually it's a bad idea to have public nested types.

Can you tell us more about what you're trying to achieve? There may well be a better approach.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I was wanting to call a method and then have options about what to do with the code. For example I pass a string argument to the Method, then I could call either of 2 nested methods depending on what I wanted to do with the string, maybe one method would convert to int, the other a double, something like that. Thanks – Bali C Nov 15 '11 at 10:50
  • 4
    @BaliC: I'd probably do that with separate private methods. You *could* use anonymous functions within the public method, but just making them private and documenting the intended use would probably be simpler. – Jon Skeet Nov 15 '11 at 10:57
  • Thanks, thats what I needed help on, I wasn't sure which way to go about it. – Bali C Nov 15 '11 at 10:58
  • 1
    The example doesn't show the core feature of pascal like nested functions, namely accessing the parents variables from the nested function? Factoring it out to other entities is then useless since you either have to pass everything by params again – Marco van de Voort Jun 27 '14 at 14:35
  • @MarcovandeVoort: This question is about nested *types*, not nested *functions*. It sounds like you should probably ask a new question. – Jon Skeet Jun 27 '14 at 14:36
  • Yup, sorry, probably got confused by the question linking here. – Marco van de Voort Jun 27 '14 at 23:37
  • @AndyJoiner: Yes, indeed you can. – Jon Skeet Nov 14 '16 at 12:11
  • My mistake - I thought C# 7 was out. – Andy Joiner Nov 14 '16 at 12:42
  • 2
    @Andy: Well it nearly is - but it certainly wasn't in 2011 :) – Jon Skeet Nov 14 '16 at 12:49
  • C# 7 is out now so basically, Yes you can do this. Go nuts. – Canvas Oct 19 '17 at 15:56
27

You can define delegates within your method with complete code and call them if you want.

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

   }
}

There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:

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

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

}
Alexander Galkin
  • 12,086
  • 12
  • 63
  • 115
10

As of C# 7.0 you can do that:

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

     Hi();
 }

This is called local functions, that is just what you were looking for.

I took the example from here, but further informatin can be found here and here.

Steve
  • 4,415
  • 1
  • 19
  • 30
Luis Teijon
  • 4,769
  • 7
  • 36
  • 57
4

Why you don't use classes?

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

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

Now you can acces MethodA via

Helper.MethodA();
masterchris_99
  • 2,683
  • 7
  • 34
  • 55
3

Older thread, but C# does have the concept of nested functions

    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
    }
oldSchool
  • 31
  • 3
  • Might be worth mentioning when this was added as IIRC this was added recently enough that it might not be available in everyone's environment. Also `calcArithmatic` might not be the best name for a function that returns a function and does no actual arithmetic. – zzxyz Nov 30 '17 at 19:57
  • I think that's valid on both points. I updated the method name. – oldSchool Dec 01 '17 at 20:55
1

Your nearly there

public static void Method1()

should be

public static class Method1{}
Juri
  • 32,424
  • 20
  • 102
  • 136
Ash Burlaczenko
  • 24,778
  • 15
  • 68
  • 99
1

Don't you want to use nested class instead?

That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.

JiBéDoublevé
  • 4,124
  • 4
  • 36
  • 57
-3

Why don't you just Run a method within another

public void M1() { DO STUFF }

public void M1() { DO STUFF M1(); }