- Mastering Visual Studio 2017
- Kunal Chowdhury
- 690字
- 2025-04-04 18:47:05
Local functions or nested functions
C# 7.0, which comes with Visual Studio 2017, allows you to write local functions or nested functions. The local function provides you with the ability to declare methods/functions inside an already defined methods body. It has the same capability as normal methods, but it will be scoped to the method block where they are declared.
In earlier versions of C#, we needed to write the method bodies separately and then we needed to call one method from the other. Here is the old way to write a method called by another method:
public static Person GetBloggerDetails() { return new Person { FirstName = "Kunal", LastName = "Chowdhury", Blogs = GetBlogs() }; } private static List<string> GetBlogs() { return new List<string> { "http://www.kunal-chowdhury.com" }; }
In the preceding example, although the GetBlogs method is private, it is accessible to the other members of the same class and is being detected by IntelliSense. To overcome this, C# 7.0 introduced local functions (nested functions), by which you will be able to add a number of local/nested functions within a function/method body, constructor, or property's getter and setter. Here's how to do it:
public static void CalculateOne() { double a = 5, b = 3; double Sum(double x, double y) { return x + y; } double Subtract(double x, double y) { return x - y; } double Multiply(double x, double y) { return x * y; } void Print(string msg, double value) { Console.WriteLine(msg + value); } Print(string.Format("Sum of {0}, {1} is: ", a, b), Sum(a, b)); Print(string.Format("Difference of {0}, {1} is: ", a, b),
Subtract(a, b)); Print(string.Format("Multiplication of {0}, {1} is: ", a, b), Multiply(a, b)); }
Here you can see that the Sum, Subtract, Multiply, and Print methods are local to the CalculateOne method. So, no one other than the callee will have access to it. That means, only the CalculateOne method from the preceding example will have access to those local methods, thus, making your code more secure:

It's not mandatory to pass a parameter to the inline method. You can use the variables already in scope of the main method (callee). Here's an example for your quick reference:
public static void CalculateTwo(int a, int b) { Print(); void Print() { Console.WriteLine("Sum of {0}, {1}: {2}", a, b, (a + b)); } }
Once you run the preceding code snippet, you will see the following output in console window:

You can also utilize the same capabilities as a normal function here. For example, you can easily use generics, ref and out parameters, dynamic, async and await within a local function and achieve all the things that a normal function does. The following code block returns an out parameter from a local function:
public static void CalculateThree() { void Sum(int x, int y, out int result) => result = x + y; int retValue = 0; Sum(5, 3, out retValue); Console.WriteLine("Result: " + retValue); }
The local function supports Caller Info Attributes (CallerMemberName, CallerLineNumber, CallerFilePath). Here's an example:
public static void PrintMethodDetails() { void Print([CallerMemberName] string name = null, [CallerLineNumber] int line = 0, [CallerFilePath] string filePath = null) { Console.WriteLine("The method name is: " + name); Console.WriteLine("The method line no. is: " + line); Console.WriteLine("The file path is: " + filePath); } Print(); }
The preceding code snippet will result in the following output:

You can declare a local function with the same name as the member method and the local function will hide it:
public static void DisplayText() { void Print() { Console.WriteLine("Print from local function"); } Print(); } public static void Print() { Console.WriteLine("Print from member method"); }
Here you can see that, although a member method named Print is there, it called the local function instead of the member method:
