Generic collection interface rules

I am having some problems understanding how to use interfaces within the generic collection framework. I expected the code below to work.


publicinterface Reader
{
string GetValue();
}

publicinterface ReadWriter : Reader
{
void SetValue(string value);
}

publicclass MyReadWriter : ReadWriter
{
privatestring value;

publicstring GetValue() {return value; }
publicvoid SetValue(string value) {this.value = value; }
}


[TestFixture]
publicclass Tester
{
private IDictionary<string, ReadWriter> readWriters =new Dictionary<string, ReadWriter>();

public IDictionary<string, Reader> GetReaders()
{
return readWriters;
}

private IDictionary<string, ReadWriter> GetReadWriters()
{
return readWriters;
}

publicvoid UpdateFred(string value){
IDictionary<string, ReadWriter> collection = GetReadWriters();
if(collection.ContainsKey("Fred")){
collection["Fred"].SetValue(value);
}
}

[Test]
publicvoid TestGenericCollectionBehaviour()
{
IDictionary<string, ReadWriter> readWriters = GetReadWriters();
IDictionary<string, Reader> readers = GetReaders();
}
}

But is generates a compile error in GetReaders().
error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IDictionary<string,Test.ReadWriter>' to 'System.Collections.Generic.IDictionary<string,Test.Reader>'. An explicit conversion exists (are you missing a cast?)

I then tried to add a cast as follows



public IDictionary<string, Reader> GetReaders()
{
return(IDictionary<string, Reader>)readWriters;
}

This compiled but when I ran the code I got a run time error as the same point

Test.Tester.TestGenericCollectionBehaviour : System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.Dictionary`2' to type 'System.Collections.Generic.IDictionary`2'.

It seems to me that this should be possible (certainly no unsafe casts needed) but does not seem to work like this. I have have not managed to find any details of the rules surounding the contents of generic collections - any recommendations?

[4051 byte] By [JulianMackintosh] at [2008-2-12]
# 1
I (and several others I imagine) have made this same assumption. However, it's invalid. Why, you ask? Because a Dictionary of ReadWriters is NOT a Dictionary of Readers. Imagine what would happen if you added a Reader to the Dictionary of ReadWriters after you cast it to a Dictionary of Readers. Smile
dkocur2 at 2007-9-8 > top of Msdn Tech,Visual C#,Visual C# Language...
# 2
Thanks - when you put it like that it all makes sense Smile
JulianMackintosh at 2007-9-8 > top of Msdn Tech,Visual C#,Visual C# Language...