7

I have two interfaces:

public interface A { 
 void aMethod(); 
}


public interface B : A {
 void bMethod();
} 

Later I'm basically using a dictionary like this:

Dictionary<int, A> dict = new Dictionary<int, B>();

C# is saying I can't convert from the right to the left, even if I cast it. Is there a way to use generics in C# so that this can work? If I make them abstract classes it seems to be ok but I need these as interfaces.

5
  • 1
    What version of .NET are you using? Commented Nov 10, 2010 at 16:45
  • @Dinah: Why would the framework version make any difference in this case? Commented Nov 10, 2010 at 17:27
  • @LukeH: because .NET 4.0 has Covariance and Contra-variance which may address this. If dmurph is having this issue despite being on 4.0, the issue would be different than if the issue occurred pre-4.0 Commented Nov 10, 2010 at 17:40
  • @Dinah: C#4 introduced variance for generic interfaces and delegates, not classes, so would make no difference if trying to assign a Dictionary<int, B> to a Dictionary<int, A>. Commented Nov 10, 2010 at 22:06
  • 1
    It looks like I'm not even using 4.0. Everyone here looks correct... Commented Nov 13, 2010 at 0:46

3 Answers 3

11

The feature you are looking for is what's referred to as generics variance (covariance and contravariance). There is limited support for this starting in .net framework 4. Here's an interesting post: How is Generic Covariance & Contra-variance Implemented in C# 4.0?

And here's the MSDN entry on Covariance and Contravariance in Generics.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the msdn link, that was helpful, looks like I'll have to tackle my problem in some other way
9

Nope it's a covariance issue. If you could do:

Dictionary<int, A> dict = new Dictionary<int, B>();

It would be possible without a compiler error to put an object of Type A in dict.

The problem is that dict looks like: Dictionary<int, A> but it is really type Dictionary<int, B>() (so placing an object of Type A would throw a runtime error because of an invalid cast), so you shouldn't be allowed to even try to place an object of Type A in dict, which is why you can't do :

Dictionary<int, A> dict = new Dictionary<int, B>();

It's protecting you from making a runtime mistake.
You want to check out Eric Lippert's blog on the subject.

It's one of his favorite topics to talk about, so it's quite thorough.

Comments

2

I don't think you're going to find a way around your problem because the thinking behind it seems flawed. To illustrate, let's create another interface:

public interface C : A
{
    void cMethod();
}

Now, let's use your code:

Dictionary<int, A> dict = new Dictionary<int, B>();

What happens when I try the following?

C c = new ClassThatImplementsC(); 
dict.Add(1, c);

Take a look at Eric Lippert's Covariance and Contravarience FAQ for many, many more details.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.