为什么我的代码不支持共变接口?

时间:2012-02-08 11:54:35

标签: c# dynamic .net-4.0 covariance

根据反射器,ExpandoObject确实实现了IDictionary<string, object>

enter image description here

我怎么有这个代码,我不明白为什么接口协方差在这里不起作用

enter image description here

从我读过的内容 - 它确实可以起作用:

enter image description here

2 个答案:

答案 0 :(得分:3)

这里有三个错误:

  • IDictionary<TKey, TValue>在其类型参数
  • 中不变
  • 通用差异不适用于值类型(int此处)
  • 如果协变,你会试图以错误的方式使用它:你实际上是在尝试使用逆转

你应该忽略dynamic部分 - 这是一个红色的鲱鱼。尝试制定一些您期望的代码,使其不使用dynamic。以下是IDictionary<,>不变的原因示例:

// Suppose it were covariant in value...
Dictionary<string, string> stringToString = new Dictionary<string, string>();
IDictionary<string, object> stringToObject = stringToString;
stringToObject["foo"] = new MemoryStream();
string value = stringToString["foo"]; // Um?

// Suppose it were contravariant in value...
Dictionary<string, object> stringToObject = new Dictionary<string, object>();
IDictionary<string, string> stringToString = stringToString;
stringToObject["foo"] = new MemoryStream();
string value = stringToString["foo"]; // Um?

答案 1 :(得分:1)

  1. IDictionary<TKey,TValue>不支持任何差异 想象一下如果你可以将IDictionary<string,object>转换为IDictionary<string,int>会发生什么:
    您的界面现在保证它返回的每个值都是int。但是既然你可以向它添加任意对象,它实际上无法保证这一点。
  2. 即使支持方差的接口,也只支持引用类型之间的接口。 int不是引用类型。
  3. 此问题与动态无关。您无法将仅实现IDictionary<string,object>的类转换为IDictionary<string,int>。无论您使用静态铸造还是动态铸造。它根本没有实现该接口。