Friday, April 18, 2008

Nested functions in C#

We all have heard of nested classes, nested namespaces. Have we ever heard of nested function??? Can we write a nested function in C#???


The answer is Yes, we can write a nested function in C# using delegates. This article deals with writing nested methods in C#. Knowledge of delegates is required. For creating nested methods, we write anonymous methods and associate delegates with them.

//Declare a delegate which will point to different anonymous methods.

public delegate long FactorialDelegate(long n);


public void FunctionInFunction()

{


// Nested function.

FactorialDelegate FactorialMethod = delegate(long number)

{

if (number < 1)

throw new ArgumentOutOfRangeException(

"n", "Argument must be greater than 0!");

long result = 1;

// Calculate factorial

for (int iterator = 1; iterator <= number; iterator++)

result *= iterator;

return result;

};


// Nested function with recursion.

FactorialDelegate FactorialRecursive = delegate(long number)

{

if (number < 1) throw new

ArgumentOutOfRangeException(

"n", "Argument must be greater than 0");

// The current method will always be at the 0th frame on the stack.

MethodBase method = new StackTrace().GetFrame(0).GetMethod();

return number > 1 ? number * (long)method.Invoke(null,

new object[] { number - 1 }) : number;

};


Console.WriteLine("Factorial for 5 = " + FactorialMethod(5));

Console.WriteLine("Factorial for 10 = " + FactorialRecursive(10));

}


In the above example we have declared a delegate and in the method FunctionInFunction we are associating that delegate with two anonymous methods we defined. The first one is a normal method and the second anonymous method is recursive in nature. In the recursive method we have used reflection to get the recursive method name i.e. invoking this method. The current method will always be on the frame 0 of the stack trace.

Some properties of anonymous methods:

· It is an error to have a jump statement, such as goto, break, or continue, inside the anonymous method block whose target is outside the block. It is also an error to have a jump statement, such as goto, break, or continue, outside the anonymous method block whose target is inside the block.

· Unlike local variables, the lifetime of the outer variable (outer variable is a variable declared local to the outside wrapper function) extends until the delegates that reference the anonymous methods are eligible for garbage collection.

· An anonymous method cannot access the ref or out parameters of an outer scope.

· No unsafe code can be accessed within the anonymous-method-block.


For more info about anonymous functions click here.



0 comments:

Post a Comment