Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Generic type constraint does not enable assignment without explicit cast

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading