While reading Microsoft documentation, I stumbled on such an interesting code sample:
interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass<T>
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
It means you can cast your generic to the interface explicitly but not to the class unless you have a constraint. Well, I still cannot understand the logic behind the decision as both interface and class type castings are throwing exceptions, so why would one protect against only one of these exceptions?
BTW- there is a way around the compile error but this does not remove the logic mess in my head:
class MyOtherClass
{...}
class MyClass<T>
{
void SomeMethod(T t)
{
object temp = t;
MyOtherClass obj = (MyOtherClass)temp;
}
}
That’s exactly what you get in normal circumstances – without generics – when you try to cast between classes with no inheritance relationship:
So without a constraint, the generic class will behave as if there is no relationship between the classes.
Continued…
Well, let’s say someone does this:
And then calls:
Now you’ll see why the compiler lets the interface cast pass. It really can’t know at compile time if an interface is implemented or not.
Remember that the D class may very well be written by someone who is using your assembly – years after you compiled it. So there is no chance that the compiler can refuse to compile it. It must be checked at run time.