Casting

Casting

You may need to a cast a generic type. Since generic types are implicit System.Object types, they can always be cast to that type. In addition, generic types can be cast to the derivation constraint, which is also a type. The derivation constraint assures that the generic type is a descendant of the constraint. This assures a safe cast. Finally, generics can be cast to any interface even if the interface is not included in an interface constraint. Since there is no restriction on casting to interfaces, it is not type-safe. For that reason, care should be taken to cast to an implemented interface.

In the following code, ZClass is a generic type. It has a single type parameter (T) that has three constraints: YClass type derivation, IA interface derivation, and the constructor constraint. An instance of the T parameter is created in the method called Cast. The instance is then cast in succession to the YClass, IA, and IB interface. The first two casts work as expected. The third cast fails spectacularly. The type parameter is not related to IB. However, the compiler does not notice. Therefore, an exception is raised at run time, which is the worst possible time and underscores the type-unsafe nature of interface cast of generic types.

 public class ZClass<T> where T:YClass, IA, new() {
        static public void Cast() {
            T obj=new T();
            ((YClass) obj).MethodA();
            ((IA) obj).MethodA();
            ((IB) obj).MethodB(); // kaboom
        }
    }

    public class YClass : IA {
        public void MethodA() {
            Console.WriteLine("YClass.MethodA");
        }
    }

Generic type parameters cannot be assigned a null or zero. There is no assurance that a type parameter is either a reference or value type, which prevents safely assigning a null or zero value to a type parameter. However, you can test a type parameter against null but not zero. If the comparison succeeds, the type parameter is a reference type. Otherwise, the type parameter is a value type.