Casting Restrictions ???

We all know that the runtime can detect the actual type of a System.Object instance. The primitive data types provided by the runtime are compatible with one another for casting (assuming that we do not truncate the values). So if I have an int, it can be cast to long or ulong. All that is fine. Watch this:-
interface IAppDataTypeBase
{
   // Other methods
   GetValue();
}
Since IAppDataTypeBase represents the mother of all types of data in my application, I have made GetValue to return the value as object (I could have used generics, that is for another day!).
IAppDataTypeBase longType = GetLongInstanceFromSomeWhere();
int i = (int)longType.GetValue();
So are we discussing any problems here? Yes, we are. The problem is that the value returned by GetValue - System.Object - despite being inherently long cannot be cast to an int. It would result in an 'Specified cast is invalid' exception. If an object is one of the primitive types, it can only be cast to its actual type. In the above case, the object returned by GetValue can only be cast to long, and nothing else. The user defined data types do not have this restriction if the base type and target type are related.
class X { };
class DX : X { };
class Y { };
If GetValue returns an instance of DX, it can be cast to X or any of its base interfaces (if any). The same goes good for structs too.

So why do we have this casting restriction for the primitive types? Was this unintentional or is there an advanced CLR internals web page somewhere talking about this? Probably fixed in C#4.0? Until I learn why, the question is open.

Understanding (ref)erences !!!

Let us take a look at the following piece of code:-
public void Operate(IList iList2)
{
iList2 = new List();
iList2.Add(1);
iList2.Add(2);
iList2.Add(3);
}

public static void Main()
{
IList iList= new List();
iList.Add(10);
Operate(iList);
Console.WriteLine(iList[0].ToString());
}
Be thinking about what would the above program print to the console ? And that is what we are going to talk about in this post - simple but subtle.

I saw this code at CodeProject discussions. The author was confused with why was the program printing 10 instead of 1. I am writing about this since the 'gotcha' was not highlighted in the discussion.

So we passed the reference 'iList' to the function which is supposed to make it point to the 'List' that it creates and so must be printing 1. Well, a C++ programmer knowing how to program in C# would have said 'Gotcha' already. A reference (in C#), equivalent to a pointer in C++, is an entity that stores the address of an object in heap and accesses it using this address. So when we pass a reference (by value) to a function, then we are passing this address value. That is captured in another 4 byte variable local to that function; so creating assigning inside the function will make iList2 point to newly created object - iList and iList are two different reference pointing to the same object. So if you want to transmit the effect of the changes you make to the List inside the function, pass it by reference - use ref keyword.

Now the fun part !!! Let us try writing the same stuff in C++:-
// This function will not alter the source pointer
void Operator(IList* pList)
{
pList = new List();
pList->Add(1);
pList->Add(2);
pList->Add(3);
}

// This function will affect the source; similar to using ref in C#
// 1) const IList*& pList - Can make pList point elsewhere but cannot modify the existing object
// 2) IList* const &pList - pList cannot point to anywhere else but can modify the existing object
void Operator(IList*& pList)
{
pList = new List();
pList->Add(1);
pList->Add(2);
pList->Add(3);
}
Hope that was fun !!!

Extension Methods - A Polished C++ Feature !!!

Extension Method is an excellent feature in C# 3.0. It is a mechanism by which new methods can be exposed from an existing type (interface or class) without directly adding the method to the type. Why do we need extension methods anyway ? Ok, that is the big story of lamba and LINQ. But from a conceptual standpoint, the extension methods establish a mechanism to extend the public interface of a type. The compiler is smart enough to make the method a part of the public interface of the type. Yeah, that is what it does, and the intellisense is very cool in making us believe that. It is cleaner and easier (for the library developers and for us programmers even) to add extra functionality (methods) not provided in the type. That is the intent. And we know that was exercised extravagantly in LINQ. The IEnumerable was extended with a whole lot set of methods to aid the LINQ design. Remember the Where, Select etc methods on IEnumerable. An example code snippet is worth a thousand words:-

static class StringExtensions
{
   /// 
   /// 'this' decorator signifies that this is an extension method.
   /// It must be appear only on a public static method.
   /// Such a method is added to the public interface of the type following 
   /// the 'this' decorator.
   /// 
   public static int ToInteger(this string s)
   {
       return Convert.ToInt32(s);
   }
   
   public static string Left(this string s, int position)
   {
       return s.Substring(0,position);
   }
   
   public static string Right(this string s, int position)
   {
       return s.Substring(s.Length - position);
   }
}

You might be aware of all this hot news. But our topic of the day is neither Extension Methods nor LINQ. It is something that dates back to C++. And you will see at the end of this post that extension methods are a polished version of a C++ principle. Ok, let us try to read some code:-

int Add(SomeClass& sc, int x)
{
   // Let us get to here a little later.
}

class SomeClass
{
private: int m_nNum;
public: void SomeMethod(int n);
public: int Num const
   {
      return this->m_nNum;
   }
};

The code is simple - We have a class called SomeClass and a global function. The global function takes a SomeClass instance by reference and an integer by value. The intent of the function is to add x with m_nNum. But whether to save it to m_nNum or just return is a topic we will deal in a little while. But do we understand that the Add function and SomeClass are closely related ?

There are two principles to know in C++ to understand the relation.

Interface Principle

For a class X, all functions, including free functions, that both (a) "mention" X, and (b) are "supplied with" X are logically part of X, because they form part of the interface of X.

* Supplied with X means that the function is provided (distributed with) in the same header file as X.

So now, Add mentions SomeClass and (to keep the discussion short assume that it) is supplied with SomeClass. If that, then Add is a part of the public interface of X. That should convince you.

Koenig Lookup

When an unqualified name is used as the postfix-expression in a function call, other namespaces not considered during the usual unqualified lookup may be searched, and namespace-scope friend function declarations not otherwise visible may be found. These modifications to the search depend on the types of the arguments. Those are lines from the C++ standard and must be tough to understand like the verses in the Bible. So let us talk our language to understand that:

namespace CPP
{
     class SomeClass { };
     void Foo(SomeClass);
}

CPP::SomeClass sc;

void main() 
{
     Foo(sc);
}

Will you be still surprised that Foo(sc) call will link to the CPP::Foo ? Don't be. That is what the cryptic lines above talks about. Ok, one more example:

namespace CPP
{
   class SomeClass { };
}

void Foo(CPP::SomeClass);


void main()
{
   CPP::SomeClass sc;
   Foo(sc); // Got it ?
}

So now down to my point, Extension Methods is a polished version of the Interface Principle (or Koenig Lookup) in C++. The facility has been in C++ for a long time but not sure if exercised well (and wisely). Had the intellisense been intelligent enough, C++ would claimed it a mighty feature. Since the C++ IDE has been the same sucking way for a long time now, C++ got the wrong outlook - a hard programming language.

Hey C#, No hard feelings. It is just a perspective. Either way, My compiler compiles your compiler.