New Features in C# 2.0 : Part 2


Iterators

Iterators are a new syntax to create a common idiom using much less code. The easiest way to walk through the subitems of a data container is a foreach loop, as you do with collections and dictionaries. But it's possible to walk through other classes, too. For example, the string class allows you to access the contained characters of type char in the same way.

A typical example for the enumeration of a class is described in the following example.It contains a foreach loop as well as the code that the compiler processes. Internally, a while loop is used that is based on the enumerator pattern.

foreach Loops Based on an Enumerator Pattern

// Implementation
ArrayList list = new ArrayList();
// ...
foreach(object obj in list)
{
DoSomething(obj);
}
// Translation through compiler
Enumerator e = list.GetEnumerator();
while(e.MoveNext())
{
object obj = e.Current;
DoSomething(obj);
}

A pattern like the IEnumerable interface has to be implemented for the class. GetEnumerator() is the only defined method, and it has to return an object that supports the IEnumerator interface. The MoveNext() and Reset() methods as well as the Current property make it possible to iterate through the class.

Iterators in C# 2.0 reduces the required implementation effort. No need to work with a design pattern; just one single typed method called GetEnumerator() is sufficient. Instead of an enumerator, the particular values will be returned directly. Here the new yield keyword replaces the old return keyword. The keyword returns a value iteratively, the next value in the sequence being returned each time you pass through the foreach loop.

Using Iterators to Iterate Through a Custom Class Refer the example given below.

using System;
using System.Collections.Generic;
public class Names
{
public IEnumerator<string> GetEnumerator()
{
yield "John";
yield "Smith";
yield "Franklin";
}
}
// Main
public class MainClass
{
public static void Main()
{
Names names =
new Names();
foreach(string name in names)
{
Console.WriteLine(name);
}
Console.Read();
}
}

The three listed names will appear within the console window.You can also use this keyword in loops as shown below ..

Using the New Yield Keyword in Loops

public class Names
{
private List<string> names = new List<string>();
public Names()
{
this.names.Add("John");
this.names.Add("Smith");
this.names.Add("Franklin");
}
public IEnumerator<string> GetEnumerator()
{
for(int i = 0; i < this.names.Count; i++)
{
yield
this.names[i];
}
}
}

The C# compiler converts the new implementation into the well-known enumerator pattern.This kind of iteration is a convenience feature. It avoids unnecessary coding and keeps the source code short.

New and therefore absolutely necessary to mention is the capability to make any method enumerable. The method has to return a value defined as IEnumerable and use the yield keyword to return each single value. Refer the example given below:

public IEnumerable GetSomeValues(int start, int stop)
{
for (int i = start; i <= stop; i++)
{
yield i;
}
}
...
foreach (int i in mc.GetSomeValues(0, 10))
{
Console.WriteLine(i);
}

Anonymous Methods

Anonymous methods let you define methods, usually delegates, inline with the declaration of the event.

You can replace this code:

button.Click += new EventHandler (this.bClick);
// elsewhere
private void bClick (sender, e)
{
MessageBox.Show ("click");
}

with the code given below:

button.Click +=
new EventHandler (object sender, EventArgs e)
{
MessageBox.Show ("click");
}

You can write the delegate's definition where you wire it to the event. These anonymous methods are members of the containing class. As such, they can view and modify members of the containing class. You can see from the previous definition that you can use the event parameters by declaring them as part of the event definition. In addition, you can assign variables to anonymous methods so you can remove event handlers later:

clickHandler = new EventHandler(sender, e)
{
MessageBox.Show("Click");
};
// Add to invocation list
button.Click += clickHandler;
// Remove from invocation list
button.Click -= clickHandler;

You can do anything with anonymous methods that you can with the event definitions you create today.

Partial Classes

This feature allows you to split a particular class into two or more separate files. For this purpose, every part of the class is marked with the new modifier partial. The compiler looks for the marked parts and merges them into one complete implementation. You'll see no difference at run time. The assembly of the code parts requires all elements be in the same project and a parallel compilation. In addition, the classes have to match logically and must be identical regarding their modifiers, supported interfaces, and so on. Attributes assigned at class level are handled automatically (Refer Example given below).

One Class Split into Several Files Using the New partial Keyword

// foo1.cs
using System;
public partial class Foo
{
public void SomeMethod()
{
}
}
// foo2.cs
using System;
public partial class Foo
{
public void SomeOtherMethod()
{
}
}

In some special cases it may be useful to split a large class into several files. But this surely won't be the general rule.One aspect you may find interesting is splitting files in conjunction with automatic code generation,as in Visual Studio.NET for example. Instead of mixing generated and written code and differentiating it later on, two separate files can now be used.

Conclusion

The new C# version comes up with several helpful improvements. Generics are really cool to create class templates like for example to use with typed collections. Anonymous methods and Iterators helps to create smaller and for that more efficient code. Partial classes can be used by rapid application designers like VS .NET to separate auto generated from your custom code.

Reference : ASP.NET 2.0 Revealed, by Patrick Lorenz.