The C# 2.0 Language - What’s New (Part II)

Posted by: Suprotim Agarwal , on 3/11/2007, in Category C#
Views: 80669
Abstract: In the previous article, we explored the various new language features introduced in C# 2.0. In the last part of this two part article series, we will be delving deep into each new feature to understand and use them in our projects.
Part II: The C# 2.0 Language
 
In the previous article, we got familiar with the new language enhancements introduced in C# 2.0. Let me now explain each of these features with an example to get a better understanding of the same.
Generics
 
Classes are templates that you can use to build new objects. Generics are templates that you can use to build new classes. This code template can be applied to use the same code repeatedly. A generic class is tied to one or more specific data types.
Generics permit classes, interfaces, structs, delegates and methods to be parameterized by the types of data they store and manipulate. They are Type-independent algorithms and collections. They enable programmers to achieve a high level of code reuse and enhanced performance for collection classes. Generics are defined with left and right brackets: <T>. Here ‘T’ in <T> is the name of the type that is going to be used.
Let me demonstrate the use of Generics by taking a simple example:
namespace GenericsDemo
{
    class TestGenerics
    {      
                static void Main(string[] args)
                 {
 
      GenericsExample();
}   
 
     private void GenericsExample()
      {
            ClsGeneric<int> intGeneric = new ClsGeneric<int>(1000);
ClsGeneric<string> strGeneric = new ClsGeneric<string>("Voila");
            ClsGeneric<float> fGeneric = new ClsGeneric<float>(23.38f);
ClsGeneric<double> dGeneric = new ClsGeneric<double>(444.4);
            ClsGeneric<bool> bGeneric = new ClsGeneric<bool>(true);
 
      }
    }
 
    public class ClsGeneric<T>
    {
        public ClsGeneric(T Type)
        {
Console.WriteLine("T over here is {0} ", typeof(T).ToString());
        }
    }
}
By using a generic type parameter T, you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations.
Iterators
 
In the earlier versions of C#, in order to use the for-each loop, you need to implement the IEnumerable interface which in turn demands the implementation of the GetEnumerator() method. This method returns an IEnumerator object using which you can use the foreach loop.
An iterator on the other hand, enables you to support foreach iteration in a class or struct without having to implement the entire IEnumerable interface.
Let me demonstrate this with an example :
public class StringCollection : System.Collections.IEnumerable
{
    string[] names = { "Tom", "Dick", "Harry”, "Ralph", "Jack", "Jill” };
 
    public System.Collections.IEnumerator GetEnumerator()
    {
        for (int i = 0; i < names.Length; i++)
        {
            yield return names[i];
          // In C#1.x you would have specified it using
          // return names[i].GetEnumerator();
        }
    }
}
 
class TestStringCollection
{
    static void Main()
    {
        // Create an instance
        StringCollection strNames = new StringCollection();
 
        foreach (string name in strNames)
        {
            System.Console.WriteLine(name);
        }
Console.WriteLine("Press any key to continue...");
      Console.ReadKey();
    }
}
 
Partial Classes
 
C# 2.0 introduces the concept of partial type definitions for classes, structs, and interfaces that allows you to define a C# type across multiple *.cs files. This leads to easier maintenance and development as more than one developer can simultaneously write the code for the class.
public partial class A
{
          public void methodA()
          {
                   // Code for methodA
}
}
 
public partial class A
{
          public void methodB()
          {
                   // Code for methodB
          }
}
Nullable Types
 
A type is said to be nullable if it can be assigned a value or can be assigned a null reference. This change makes it easier to integrate with databases, especially for fields that are optional.
A null type is very similar to its equivalent non-nullable type. The difference lies in how it is declared. For example : To declare an integer, you would declare it like this :
int iVal = 1; 
However in order to enable iVal to store a null value, you will declare it like this :
int? iVal = 1;
 
Now the way to define any valuetype as a nullable type is to define the generic System.Nullable<T> type. So the syntax to define a nullable integer is:
System.Nullable<int> iVal;

However this is somewhat difficult to read and that is why C#
provides a cleaner syntax for the nullable type by adding a
question mark to the immediate right of the type name when
defining a variable. The Syntax is [Value-Type]?
So System.Nullable<int> iVal and int? iVal are equivalent. 
Similarly you can also assign it a value null and use the HasValue and Value read-only properties to test for null and retrieve the value. Here’s an example :
int? iVal = null;
if (iVal.HasValue == true)
{
      System.Console.WriteLine("iVal = " + iVal.Value);
}
 else
 {
      System.Console.WriteLine("iVal = Null");
 }
Anonymous Methods
 
Anonymous methods help you reduce the coding overhead in instantiating delegates, by eliminating the need to create a separate method. This construct allows you to directly associate a block of code statements to a given event. In general, you can use anonymous methods anywhere you can use a delegate. An anonymous method consists of the keyword delegate, an optional parameter list, and a statement list enclosed in { and } delimiters. In some cases, the anonymous methods can omit the parameter list.
public class frmOld : Form
{
 // This method connects the event handler.
 public frmOld()
 {
    InitializeComponent();
    btnOld.Click += new EventHandler(ButtonClick);
 }
 
 // This is the event handling method.
 private void ButtonClick(object sender, EventArgs e)
 {
    MessageBox.Show("Old method of handling ButtonClick");
 }
}
Using Anonymous methods :
public class frmNew : Form
{
 public frmNew()
 {
    InitializeComponent();
 
    btnNew.Click += delegate(object sender, EventArgs e)
    {
 
MessageBox.Show(“New way of handling button click using anonymous methods");
    };
 }
}
// Declare a delegate
delegate void PrintHello(string str);
 
class TestAnonymous
{
    static void Main()
    {
          hello = new PrintHello(TestAnonymous.TestMethod);
Without anonymous method you would associate the delegate with a named method. For eg:
 
hello = new PrintHello(TestAnonymous.TestMethod);
 
//and declared a method to associate it with the named delegate
 
 
static void TestMethod(string test)
{
   System.Console.WriteLine(test);
}
 
Static Classes
Static classes are classes that contain only static members. These static members can be initialized only by using static constructors. The data and functions that these classes create, can be accessed without creating an instance of the class. Static classes are sealed so they can not be inherited. TheSystem.Math class is an example of this construct.
Static classes can be used when there is no data or behavior in the class that depends on object identity. One of the advantages of static classes is improved performance. Since there is no instantiation of object, the framework maintains a single object in memory for static members. They are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace containing the class is loaded.
Creating a static class is much the same as creating a class that contains only static members and a private constructor. A private constructor prevents the class from being instantiated. Lets see an example of a static class. 
 
Property Accessor Accessibility
 
Properties provide flexibility to read and write the values of private fields. They can be used as though they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily while still providing the safety and flexibility of methods.
In C# 1.x, we declare a property in our class in the following manner:
    class ClsProp
    {
        private string strMyName = "Suprotim";
 
        public string StrMyName
        {
            get { return strMyName; }
            set { strMyName = value; }
        }
    }
Here the ‘get’ and the ‘set’ accessors have the same accessibility level i.e., they are both ‘public’ as the property itself is ‘public’. However, it is sometimes useful to restrict access to one of these accessors, which was not possible for us in C# 1.x.
In C# 2.0, this has changed :
public string StrMyName
{
    get
    {
        return strMyName;
    }
    protected set
    {
        strMyName = value;
    }
}
 
In this example, a property called StrMyName defines a get and set accessor. The get accessor receives the accessibility level of the property itself, public in this case, while the set accessor is explicitly restricted by applying the protected access modifier to the accessor itself.
Note : This feature of having Accessor Accessibility was provided in C# v1.0 beta. However Microsoft removed it before the C# v1.0 RTM as they felt it was too complicated for developers. In C# 2.0, it has been re-introduced.
Covariance and Contravariance
 
In .NET 1.1, delegates could only be created with methods whose arguments strictly matched the signature of that delegate. With .NET 2.0, Covariance and contravariance provide a degree of flexibility when matching delegate methods with delegate signatures.
 
Conclusion
 
In this article, we explored the various new features introduced in C# 2.0. I hope the information was useful and I thank you for viewing it.
Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles
Suprotim Agarwal, ASP.NET Architecture MVP, MCSD, MCAD, MCDBA, MCSE, is the CEO of A2Z Knowledge Visuals Pvt. He primarily works as an Architect Consultant and provides consultancy on how to design and develop .NET centric database solutions.

Suprotim is the founder and primary contributor to DotNetCurry, DNC .NET Magazine, SQLServerCurry and DevCurry. He has also written an EBook 51 Recipes using jQuery with ASP.NET Controls. and is authoring another one at The Absolutely Awesome jQuery CookBook.

Follow him on twitter @suprotimagarwal


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by kanakaiah on Thursday, August 16, 2007 4:18 AM
helped to know new things in c#2.0 thanks
Comment posted by Anupama on Friday, January 25, 2008 12:26 AM
Excellent....
Comment posted by Ankit on Monday, February 25, 2008 10:29 AM
I want to Know deeply about c# Keywords
Comment posted by Suprotim Agarwal on Monday, February 25, 2008 12:15 PM
Hi Ankit, This link will help you out http://msdn2.microsoft.com/en-us/library/x53a06bb(vs.71).aspx
Comment posted by Shashidhar Rao on Tuesday, February 26, 2008 7:42 AM
help me new things to learn in c# 2.0 Interview Questions also plz mail to my ID
Comment posted by heaiping on Thursday, December 4, 2008 8:37 AM
thanks a lot!
Comment posted by laxman F. Patil (NIC) on Friday, January 9, 2009 3:22 AM
thanks a lot sir!
Comment posted by Pavan Kumar S on Thursday, April 8, 2010 8:55 AM
Nice Article. It helped Me a lot. Thanks dude. Keep the good work going. .  .
Comment posted by dericktener on Friday, June 3, 2011 4:36 AM
Hi,

Speaking about what is new in C# Language I have found a Command line caller that is written in it.
Calls can be made from this command line caller and there is no need for a graphical user interface to run the program.

If you are interested it can be found here:
http://voip-sip-sdk.com/p_163-c-command-line-caller-voip.html

Derick
Comment posted by Nagesh on Wednesday, June 27, 2012 7:36 AM
hi

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel