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

Is C# element inside Tuple cannot be upcasted?

I’m encountering a compilation error in C# .NET 8.0 when trying to pass a Dictionary with a tuple as its key to a method. The tuple consists of a base class and another class, but when I try to use a derived class in place of the base class within the tuple, the code fails to compile. Here’s a simplified version of my code:

class A{};
class B : A {};
class X{};

void bar(Dictionary<(A sup, X oth), X> MyDicArg) {
    // Do something with Dictionary using that tuple
}

void foo() {
    var arg = new Dictionary<(B sup, X oth), X>();
    bar(arg); // Compilation error here
}

Since B is a subclass of A, I thought I could use a Dictionary with a key of (B, X) where a Dictionary with a key of (A, X) is expected due to implicit upcasting, but it does not seem to happening.

Could someone explain why this type mismatch occurs and how I might work around this issue? Is there a way to make the method accept a dictionary with a derived class in the tuple key, or do I need to adjust my approach?

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 term you are looking for is covariance (And its relative, contravariance.) Unfortunately, tuples in C# are neither covariant nor contravariant, because they are structs, not interfaces, and in C# only interfaces support covariance/contravariance.

In your specific example you should consider the limitation as just fine, because if this limitation was not there, you would be allowed to potentially shoot yourself in the foot.

This is because foo() has a dictionary of a more-derived class, and you wanted it to hand-out this dictionary to bar() which would treat it as containing a less-derived class, but you are using Dictionary, not IReadOnlyDictionary, so bar() is free to add a less-derived class into the dictionary, thus wreaking havoc into foo().

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