Implementing Nested Functions in C# San Jose CA

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

cccp
408-265-2902
2585 Westgate Ave
San Jose, CA
Accoladde
+91 9962299053
2033 Gateway place
San Jose, AK
Accoladde
+1 408 651 7050
2033 Gateway Place
San Jose, CA
Concierge for Business
408 993-1368
472 Clifton Avenue
San Jose, CA
VeriPIc
1-888-837-4742
2360 Walsh Ave
Santa Clara, CA
Zoniac, Inc.
619.448.7284
1649 S. Main Street, Ste. 105
Milpitas, CA
InsidersReferral.com, Inc.
(408) 338-6542
386 America Ave
Sunnyvale, CA
TrueSoft, Inc.
408-329-3011
440 N. Wolfe Rd.
Sunnyvale, CA
Accept Software Corporation
1.866.423.8376
42808 Christy Street, Suite 216
Fremont, CA
smartData Enterprises
646-367-8215
706 Colorado Avenue,
Palo Alto, CA 94303, CA

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

cccp

408-265-2902
2585 Westgate Ave
San Jose, CA
http://cccptech.com

Related Local Events
MACWORLD 2010
Dates: 1/4/2010 - 1/8/2010
Location: Moscone Convention Center
San Francisco, CA
View Details

Informex USA
Dates: 2/16/2010 - 2/19/2010
Location: Moscone Convention Center, San Francisco
San Francisco, CA
View Details

Advanced Lithography
Dates: 2/21/2010 - 2/26/2010
Location: San Jose Convention Center
San Jose, CA
View Details

Contraceptive Technology Conference : San Francisco
Dates: 3/24/2010 - 3/27/2010
Location: Hyatt Regency Hotel
San Francisco, CA
View Details

Web 2.0 Summit
Dates: 10/20/2009 - 10/22/2009
Location: Westin San Francisco Market Street
San Francisco, CA
View Details