Вы не можете напрямую приводить или преобразовывать экземпляр универсального типа в экземпляр типа с другими универсальными параметрами, ЕСЛИ ОБЩИЙ универсальный тип специально не определен как ковариантный (может рассматриваться как универсальный для базового класса фактического типа). объявленный универсальный тип) для этого конкретного параметра универсального типа, И вы пытаетесь привести тип к универсальному из базового класса его фактического типа. Например, IEnumerable<string>
может рассматриваться как IEnumerable<object>
, потому что строка происходит от объекта. Он не может рассматриваться как IEnumerable<char>
, даже если все строки имеют только один символ, потому что String не является производным от Char.
Ковариация определяется в C # 4.0 с помощью ключевого слова out
для универсального параметра, но, насколько мне известно, в отличие от IEnumerable, универсальный интерфейс IDictionary не указан как ковариантный. Кроме того, несмотря на то, что словарь является IEnumerable, он представляет собой IEnumerable из общих пар ключ / значение, и универсальные KVP не являются ковариантными, поэтому нельзя рассматривать универсальные параметры KVP как базовые типы.
Что вы можете сделать, это создать новый словарь нового типа и перенести все значения из старого. Если эти значения являются ссылочными типами, то при изменении подзначения одного из значений в словаре с типом ссылки он будет изменен в соответствующем значении другого словаря (если только вы не измените саму ссылку, назначив для этого нового экземпляра MyClass значение. ключ).
Маленький Линк делает это довольно легко:
Dictionary<string, MyClass> MyStronglyTypedDictionary =
new Dictionary<string, MyClass>();
//populate MyStronglyTypedDictionary
//a Dictionary<T1, T2> is an IEnumerable<KeyValuePair<T1, T2>>
//so most basic Linq methods will work
Dictionary<string, object> MyGeneralDictionary =
MyStronglyTypedDictionary.ToDictionary(kvp=>kvp.Key, kvp=>(object)(kvp.Value));
...
//Now, changing a MyClass instance's data values in one Dictionary will
//update the other Dictionary
((MyClass)MyGeneralDictionary["Key1"]).MyProperty = "Something else";
if(MyStronglyTypedDictionary["Key1"].MyProperty == "Something else")
{
//the above is true; this code will execute
}
//But changing a MyClass reference to a completely new instance will
//NOT change the original Dictionary
MyGeneralDictionary["Key1"] = new MyClass{MyProperty = "Something new"};
if(MyStronglyTypedDictionary["Key1"].MyProperty == "Something else")
{
//the above is STILL true even though the instance under this key in the
//other Dictionary has a different value for the property, because
//the other dictionary now points to a different instance of MyClass;
//the instance that this Dictionary refers to never changed.
}