C# Tips part-I

C# generics syntax is elegant 

C# generics syntax is much better than the nearest contender C++. Consider the following generic declaration in C++

template <typename T> // can use <class T> as well

class GenClass

{

};

I always felt the need to use the typename keyword is without any purpose. Most developers kept using <class T>. The designers of C# showed that the usage of template is also not required. The short and sweet syntax in C# is

class MyClass<T>

{

}

Constraint syntax sucks

This does not mean that everything is as small and sweet in C#. The usage of the struct keyword to indicate value type constraint is one such example. Say for a generic type I want to put a restriction that the type parameter can only be a value-type. I have to do it as follows

class MyClass<T> where T: struct

{

}

MyClass<int> mc = new MyClass<int>();


This is very un-intuitive because even for integral types like Int I need to use struct as the constraint.  Similar issue is with specifying constraints on multiple type parameters. Consider the following

class MyClass<T,U> where T: struct where U: class

{

}


Only if I break the constraint to two lines can you read it

class MyClass<T,U> where T: struct

                   where U: class

{

}


There should have been some delimiter in between consecutive where to make the whole thing more readable. 

The rules regarding the order of constraints initially taxes your memory but you get used to it soon. If I need a constraint that the type has to be a reference type that must have a public parameterless constructor I need to do the following

class MyClass<T> where T: class, new()

{

}


Here the order is important as class has to be the first contraint and new() has to be the last.

Enumerting all values of an Enum

Sometimes you need to do something in code and you hit on a simple solution, and then you sit back and marvel on the design that lets you do that. Sometime back when writing my blog on the usage of console color I needed to write some code that got all the values for the Enum ConsoleColor and print text using those colors. I used the following code.

static void Main(string[] args)

{

ConsoleColor originalCol = Console.ForegroundColor;

    foreach(ConsoleColor color in Enum.GetValues(typeof(ConsoleColor)))

    {

        Console.ForegroundColor = color;

        Console.WriteLine("{0, -12} {1}", color, color.ToString("D"));

    }

    Console.ForegroundColor = originalCol;

}


All of this could be done so easily is because of the unified inheritance structure of .NET. All enums inherit from System.Enum and so a lot of functionality comes to you for free. You can use Enum.GetValues to do the work of getting all the values and use the base Enum types ToString overrides to give you correct string/value representations of the enum. Try doing this in C++ and the difference is evident. 

The fact that I could do this so easily made me extremely happy. Programmers should be lazy and a language or framework that allows them to be lazy should be the platform of choice. 

Generic methods, delegates and type inference in C#2.0.

I did not like var in C# 3.0 because I felt it reduces code readability. For the same reason I do not like using Type-Inference in C# 2.0 generics. 


class MyClass

{

    public void MyMethod<T>(T value) {

        Console.WriteLine("{0} {1}", typeof(T).FullName,
                                     value.ToString());

    }

}

class Program

{

    static void Main(string[] args)

    {

        MyClass mc = new MyClass();

        mc.MyMethod(5);       // Type inference

        mc.MyMethod<int>(12); // Explicit type parameter

    }

}


Even though the first one using type inference requires less typing (and I'm sure will go a long way in CTS erradication) I prefer the more verbose explicit type parameter.

However when applied to generic delegates, type inference becomes a bit different. Consider the following

class MyClass

{

    public delegate void Foo<T>(T item);

    private void Bar(int i)

    {

        Foo<int> foo = MyMethod; // MyMethod<int> is inferred

        //Foo foo = MyMethod<int>;

    }

    public void MyMethod<T>(T value)

    {

    }

}

I was talking to a friend some-time back and when compared to generic methods, he had assumed that type inference for generic delegate would mean that the type parameter of the delegate will be inferred. However as we see from the example above that the type of the delegate needs to be explicitly given and from this the type of the generic method is inferred. I am kind of OK with this because at least the types are specified in the statement.

Mixins and C#

In one of my previous lives when I first heard about mixin and tried to look it up I hit into various conflicting definitions. The definition of Mixin I settled for is "MixIn programming is a style of software development where units of functionality are created in a class and then mixed in with other classes". In C++ two common ways of doing this is multiple-inheritance and parameterized Abstract Sub Class (yep not Abstract Base class). I'll not get into MI because the basic design of C# will never allow it. However C# may be expanded to include Mixin using generics.

Mixin in C++

The definition of mixin above is pretty general. Even though mixin is a class it is intended to be combined with other classes and not to be used standalone. Mixins can be defined using parameterized inheritance of Abstract Sub class as follows

template <typename Base>

class MyMixin : public Base

{

};

template <typename Base>

class AnotherMixin : public Base

{

};

 

MyMixin<AnotherMixin<string> > mm;


In the above code both MyMixin and AnotherMixin derive from the type parameter passed to it. They are Abstract Sub classes because their super classes are not pre-determined. It is possible to chain them to create a singly inherited hierarchy so that the combined class gets the public functionality of all the mixin classes in the chain. Lets take a look at a more concrete example.

#include <iostream>

#include <string>

#include <ctime>

using namespace std;

 

template <typename T>

class AgeProvider : public T

{

    time_t createdOn;

public:

    AgeProvider() {

        time(&createdOn);

    }

    double age() {

        time_t currTime;

        time(&currTime);

        return difftime(currTime, createdOn);

    }

    string CreatedOn () { return ctime(&createdOn); }

};

 

template <typename T>

class CountProvider : public T

{

    static unsigned counter;

public:

    CountProvider() {

        CountProvider::counter++;

    }

    unsigned GetCount() {

        return counter;

    }

};

template<class T> unsigned CountProvider<T>::counter = 0;


typedef
AgeProvider<CountProvider<string> > TrackedString;

 

int main(int argc, char* argv[])

{

    AgeProvider<CountProvider<string> > tstr;

    tstr.append("Abhinaba ");

    tstr.append("Basu");

    cout << "Content : " << tstr << endl;

    cout << "Created : " << tstr.CreatedOn();

    cout << "Age : " << tstr.age() << endl ;

    cout << "Count : " << tstr.GetCount() << endl;

    return 0;

}


Here the first mixin class in AgeProvider which gives info on the age in seconds of an instance of the class as well as when the instance was created. The other mixin is CountProvider, which gives how many instances of a specific class, was ever made. Both of these classes have no use on their own. However when they are mixed together with a stand-alone class like string they provide the funtionality of counting and age to that class. Interestingly the whole of the above works without any multiple-inheritance and not imposing any restriction on the Mixin classes on what they inherit from or the inheritance order.

Mixins In C#

Some suggest that extension methods in the upcoming C# 3.0 are a kind of Mixins, because you can put in functionalities in these methods and arbitrarily tag it onto any class you want. In the C# 2.0 specification section 20.1.3 it is clearly called out that the base class of a generic class has to be a constructed class type so this rules out using the above approach to be used in C#. I am not too sure on why we choose to explicitly disallow abstract subclass. Since C# does not support multiple-inheritance, IMO it should have supported Mixin style coding.

C#: Fast string comparison optimization

Sometime back I had blogged about using reference comparison to speed up ordinal string comparisons. Essentially this means that if you know for sure that your string is interned and you want to do an ordinal string comparison you can use the following optimization

if (command == "START")

    Console.WriteLine("Starting Build...");

else if (command == "STOP")

    Console.WriteLine("Stopping Build...");

 

// Optimization

if (Object.ReferenceEquals(command,"START"))

    Console.WriteLine("Starting Build...");

else if (Object.ReferenceEquals(command, "STOP"))

    Console.WriteLine("Stopping Build...");


This works only if the string command is an interned string. If its not (e.g. its accepted from command lines or is constructed) you can intern it using something like string internedCmd = string.IsInterned(command) ?? string.Intern(command); and then use the interned version of the same string.

However an email to the internal CSharp alias made me look again. The email stated that the static method String.Equals(a,b) is more efficient than instance method String.Equals(a). I looked in into the code and it appears that for static Equals we already do the reference comparison first, while for instance Equals we jump right to string comparison.

// Static Equals called from overloaded operator ==public static bool Equals(string a, string b)

// Static Equals called from overloaded operator ==

public static bool Equals(string a, string b)
{
if ((object)a == (object)b)
{
return true;
}
if ((a != null) && (b != null))
{
return string.EqualsHelper(a, b);
}
return false;
}


This might get fixed in future .NET version when both Equals will do the reference comparison first. However, the optimization I suggested does not hold because its already been done in the framework right now.

So currently in the following snippet the second version is faster than the first
string a = ...;
string b = ...;


a.Equals(b);
string.Equals(a, b); // faster


You can reach author from the following URL.


abhinaba@gmail.com




Added on September 13, 2007 Comment

Comments

Post a comment