Home > database >  Generic type constraint does not enable assignment without explicit cast
Generic type constraint does not enable assignment without explicit cast

Time:06-11

I can't believe in my many years of C# experience it has taken me this long to discover the following limitation, and I can't quite believe this is unavoidable, if anyone can illuminate me to the contrary I would be very pleased. Consider the following:

namespace ConsoleApp1;

internal class BaseClass { }

internal class DerivedClass : BaseClass { }

internal class CastingExperiment
{
    public void AssignmentAttempts<TBase>(object anyRandomThing)
        where TBase : BaseClass
    {
        BaseClass baseClass = new DerivedClass();
        TBase wantToDoThis = new BaseClass(); // Compiler says no, cannot implicitly convert type
        TBase haveToDoThis = (TBase)baseClass;
        TBase whichIsAsEvilAsThis = (TBase)anyRandomThing;
    }
}

I'd far sooner avoid the explicit cast in this scenario, the type constraint is right there to tell the compiler what it needs to know about the assignment compatibility but still the cast is required.

I've also tried deriving CastingExperiment from an interface and with either covariant or contravariant constraints for TBase and it still insists on the cast. Am I missing something?

CodePudding user response:

The constraint where TBase : BaseClass means that TBase can be any type that IS BaseClass - it can be BaseClass or any derived from it.

When you create new instance using new BaseClass(); you should have a reference of the same type (BaseClass), but your reference type is TBase (which can be any derived type).

So when you call your method like this:

someInstance.AssignmentAttempts<DerivedClass>(someArg);

then non-working line will result in something like this:

DerivedClass wantToDoThis = new BaseClass(); // check the reference type

If you just write code this way (without generics) you'll get compile time error.

You can cast derived types to base ones, but not vice versa.

  • Related