13

Is it possible to create a function inside another function in C#? If so, how can this be done?

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
ratty
  • 13,216
  • 29
  • 75
  • 108

5 Answers5

17

It is most certainly possible.

You can create delegates, which are functions, inside other methods. This works in C# 2.0:

public void OuterMethod() {
    someControl.SomeEvent += delegate(int p1, string p2) {
        // this code is inside an anonymous delegate
    }
}

And this works in newer versions with lambdas:

public void OuterMethod() {
    Func<int, string, string> myFunc = (int p1, string p2) => p2.Substring(p1)
}
Eilon
  • 25,582
  • 3
  • 84
  • 102
  • Really interesting, I learnt something :) Could you give use cases for those "delegates" that are created inside other functions please ? – Andy M Jan 12 '10 at 06:57
  • These types of delegates and lambdas are often used when a piece of code is so small it's not worth giving it a name. This other SO question goes a bit more into when it could/should be used: http://stackoverflow.com/questions/2047053/when-should-i-use-lambda-expressions-which-comes-with-c-3-0 – Eilon Jan 12 '10 at 07:03
  • I use it fairly often to declare a job for a BackgroundWorker: http://stackoverflow.com/questions/1952201/display-progress-bar-while-doing-some-work-in-c/1969933#1969933 – Oliver Jan 12 '10 at 07:47
  • Is there way to call myFunc recursively inside the body? – Furqan Safdar Sep 26 '15 at 19:28
  • @FSX sure, just call `myFunc` from within itself - but set it to `null` first so that the compiler won't complain about using an unassigned variable. – Eilon Sep 29 '15 at 05:19
12

You can do this in c# 7(need VS 2017)

static void Main(string[] args)
{
    int fib0 = 1; //!
    int Fib(int n) => (n < 2) ? fib0 : Fib(n - 1) + Fib(n - 2);

    Console.WriteLine(Fib(7));
    Console.ReadKey();
}

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions

prime23
  • 3,362
  • 2
  • 36
  • 52
12

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 funtions, that is just what you were looking for.

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

prime23
  • 3,362
  • 2
  • 36
  • 52
Luis Teijon
  • 4,769
  • 7
  • 36
  • 57
-1

It's so not code smell that X++ has it done in the simplest way possible...

public void PublicMethod() {
    void LocalMethod() {
        //do stuff
    }

    LocalMethod();
}

see http://msdn.microsoft.com/en-us/library/aa637343.aspx

-2

Eilon's answer is technically correct in that you can use delegates to effectively create a method within a method. The question I would ask is why you need to create the function in-line at all?

It's a bit of a code smell to me. Yes, the internal method is reusable to the rest of your method, but it suggests that there is an element of the code where the design hasn't really been thought through. Chances are, if you need to use a delegate in this way, you would likely to be doing something fairly small and repetitive that would be better served as a function in the class, or even in a utility class. If you are using .Net 3.5 then defining extensions may also be a useful alternative depending on the usefulness of the code being delegated.

It would be easier to answer this question better if you could help us to understand why you feel the need to write your code in this way.

S.Robins
  • 703
  • 6
  • 6
  • 10
    Not fully convinced about the code smell bit. For me it's no different that declaring a local variable. You create a local variable for a local purpose, nobody uses it and it's not worth promoting it to a field of the class. The same goes with lambdas - just declare a local function. – Mathias Jan 12 '10 at 07:59
  • To clarify, the "smell" is that even with lambdas, you could find the same small snippets of code being repeated all over a large application. It might not seem likely until you take into account the inherent problem with unmonitored Cut-Paste coding. And yes, repetitively using the same pattern of local variables could be seen in the same way. I'm not saying not to use lambdas or in-line delegates mind you, just noting that they shouldn't be used as a substitute for taking the time to design your algorithms properly. – S.Robins Jan 12 '10 at 10:47
  • 5
    This is all nonsense. Local functions avoid cut and paste rather than create it, and they put logic as close as possible to where it is needed. There is no reason to expect snippets of specialized code that need to be repeated in a method to be needed anywhere else. If that need arises, they can be refactored. This is no less true for individual non-repeated lines of code ... it would obviously be absurd to turn each one into a class method *just in case* some other method needs it some day. – Jim Balter Jun 22 '14 at 08:51
  • 4
    Turning a local function into class methods could be seen as namespace pollution and hides the interface and intent of the containing class. – Jim Hansson Oct 06 '14 at 22:32