Implementing Nested Functions in C# Portland OR

Want to test just how broad and expressive a language C# is? Learn how to implement nested functions for C#, which so closely models nested functions that nested behaviors practically exist already for the language.

Local Companies

Cascade Custom Software
503-922-0135
1000 SW Broadway
Portland, OR
Advantyx Software LLC
503-246-9299
6501 SW Macadam Ave
Portland, OR
Aravo Solutions
503-224-4049
2627 NW Nicolai St
Portland, OR
Axis Clinical Software Inc
503-292-3022
6443 SW Beaverton Hillsdale Hwy
Portland, OR
Cendix
503.789.2676
501 4th Street, Suite 741
Lake Oswego, OR
Artisan Software Tools Inc
503-245-6200
10220 SW Greenburg Rd
Portland, OR
Vision33
971-255-0162
The Lincoln Center, 10260 SW Greenburg Road, 4th Floor
Portland, OR
Paradigma Software
(503) 574-2776
6107 SW Murray Blvd #151
Beaverton, OR
ClearStar.net
360-892-0687
915 Broadway
Vancouver, WA
BCSI Solutions
503-641-5584
15242 NW GreenBrier Parkway
Beaverton, OR

provided by: 
Originally published at Internet.com


If you program in more than one language, sometimes you want to use an idiom from one language in the other, where the idiom doesn't exist. So, you have to invent it for that language.

These days I write very short, well-named methods with behaviors spread over many classes. However, in the 1990s I programmed in Delphi (Object Pascal) and wrote much longer functions, sometimes using nested functions. Nested functions are functions defined within functions. They can be useful for compartmentalizing behavior that is invoked many times and at different places within a function. As well, they can be useful for naming a block of behavior within a function—even short functions.

Okay, that's a stretch. The truth is one day I was feeling creative and nostalgic, and I wanted to see if I could use nested functions in C#. What I came up with in C# so closely models nested functions that, for all intents and purposes, nested behaviors already exist for the language.

This article demonstrates how to implement nested functions for C#, and it might teach you a few things about C# in general. For the purposes of the demonstration, nested functions in C# have to behave like any other function to be useful. Therefore, they must have non-void return types, parameters, and recursion. The remaining sections demonstrate how you can effectively support all three of these elements. (Note: Some of the code isn't pretty, but it does work.)

Implementing Nested Functions Using Anonymous Delegates

To implement nested functions with parameters and return types, you need to know about delegates and another relatively new .NET capability, anonymous methods. Delegates and multicast delegates in C# (and .NET) add some additional safety nets and capabilities, but delegate really is just a fancy name for function pointer and event handler.

To begin, I picked a well-known behavior: calculating n! or n-factorial. The factorial algorithm takes a positive number n and returns 1*2*3*...n. For example, n! where n is 5 is 1*2*3*4*5 or 120. To map such a function by using a delegate signature, you can define a delegate that takes a long and returns a long, as follows: public delegate long FactorialDelegate(long n);

The preceding defines a method signature, which permits you to define delegate instances that refer to methods matching this signature. The next thing you need to do is define an anonymous method inline where you define and initialize an instance of FactorialDelegate.

Defining an anonymous method

Think of anonymous methods as similar to C++ inline methods. The real difference is that anonymous methods are function headers with code blocks but without names. (Anonymous methods are used mostly as values that are assigned to events; that is, they are inline event handlers.)

To define an anonymous method, simply define a method whose header exactly matches the delegate signature but without the word delegate. Following on the previous code snippet, it would go like this: public static long Factorial(long n) { if (n < 1) throw new ArgumentOutOfRangeException( "n", "argument must be greater than 0"); long result = 1; for (int i = 1; i <= n; i++) result *= i; return result; }

To convert the function Factorial to an anonymous method, you remove everything from the header except the parameter list (long n), add the word delegate, and leave the method body in place. The result looks like this: delegate (long n) { if (n < 1) throw new ArgumentOutOfRangeException( "n", "argument must be greater than 0"); long result = 1; for (int i = 1; i <= n; i++) result *= i; return result; }

Now, to nest this anonymous method, you can delccare an instance of FactorialDelegate and assign it the anonymous method above, as follows: FactorialDelegate Factorial = delegate(long n) { if (n < 1) throw new ArgumentOutOfRangeException( "n", "argument must be greater than 0"); long result = 1; for (int i = 1; i <= n; i++) result *= i; return result; };

In fact, what you now have is a delegate instance that can be defined in an outer method—a defacto nested function—and can be invoked just like a function. Listing 1 shows the previously defined Factorial anonymous method instance nested in the Main function of a console application.

Listing 1: A Console Application Demonstrating Nested Functions using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Text; namespace NestedFunction { class Program { public delegate long FactorialDelegate(long n); static void Main(string[] args) { // version 1 FactorialDelegate Factorial = delegate(long n) { if (n < 1) throw new ArgumentOutOfRangeException( "n", "argument must be greater than 0"); long result = 1; for (int i = 1; i <= n; i++) result *= i; return result; }; Console.WriteLine(Factorial {0} is {1}", 5, Factorial1(5)); Console.ReadLine(); } } }

Implementing Recursion

Now, you have seen a defacto nested function, but what about recursion? Unfortunately, Factorial exists after it is defined. Hence, you cannot implement n! bu using recursion. The recursive version using the very first Factorial algorithm would look like this: public static long Factorial(long n) { return n > 1 ? n * Factorial(n - 1) : n; }

My computer science professors might argue the implementation is not complete unless you can implement the entire idiom. (Of course, in business you would just do without recursion.) However, it is possible to implement recursion with nested functions. It isn't pretty, but it does work.

Listing 1 is a de facto nested function, but as I mentioned you cannot recurse by calling the variable Factorial. However, you can recurse by using reflection because even though the name Factorial doesn't exist in the anonymous method, the function does exist on the stack. Hence, all you need to do is pluck the Factorial method off the stack and call stack using reflection. Listing 2 demonstrates how you can implement nested functions using recursion.

Listing 2: A Nested, Recursive Function Using Reflection FactorialDelegate Factorial = delegate(long n) { if(n<1) throw new ArgumentOutOfRangeException( "n", "argument must be greater than 0"); MethodBase method = new StackTrace().GetFrame(0).GetMethod(); return n > 1 ? n * (long)method.Invoke(null, new object[] { n - 1 }) : n; }

The first half of the nested function in Listing 2 is the same as in Listing 1. To recurse, you need to pluck the method object off the stack; it will always be the first method entry in the stack frame. Because you also know the signature long—anonymous(long n), you can reliably invoke the method by passing the correct argument type and casting the return type. (Told you it wasn't pretty.)

Broad and Expressive Language

Because language—whether speaking or programming—limits what you can conceive, I prefer to have as broad and expressive a language as possible, one that doesn't require me to use advanced idioms but makes them available. This is

Author: Paul Kimmel

Read article at Internet.com site

Featured Local Company

Cascade Custom Software

503-922-0135
1000 SW Broadway
Portland, OR

Related Local Events
WOOD TECHNOLOGY CLINIC & SHOW 2010
Dates: 3/9/2010 - 3/11/2010
Location: Oregon Convention Center
Portland, OR
View Details

Party in the Pinot
Dates: 7/25/2009 - 7/25/2009
Location: Oswego Hills Winery
West Linn, OR
View Details

WebVisions 2009
Dates: 5/20/2009 - 5/22/2009
Location: Oregon Convention Center
Portland, OR
View Details

Technology and IP Networking Event
Dates: 5/19/2009 - 5/19/2009
Location: Oregon Zoo
Portland, OR
View Details

Fall Knit & Crochet Show
Dates: 5/14/2009 - 5/17/2009
Location: Doubletree Hotel Portland, Lloyd Center
Portland, OR
View Details