简体   繁体   English

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

[英]Why My Code doesn't support Co-variant Interface?

According To reflector , ExpandoObject Does implemenet IDictionary<string, object> 根据反射器,ExpandoObject确实实现IDictionary<string, object>

在此处输入图片说明

How ever I have this code which i dont understand why Does Interface co-variance doesn't work here 我怎么有这段代码,我不明白为什么接口协方差在这里不起作用

在此处输入图片说明

From what Ive read - it does suppose to work : 从我读过的书-它确实可以工作:

在此处输入图片说明

There are three things wrong here: 这里有三件事是错误的:

  • IDictionary<TKey, TValue> is invariant in both its type parameters IDictionary<TKey, TValue>在两个类型参数中都是不变的
  • Generic variance doesn't work across value types ( int here) 通用方差不适用于值类型(此处为int
  • If it were covariant, you'd be trying to use it the wrong way round: you're actually trying to use contravariance 如果它协变的,你会想圆使用了错误的方式:你实际上是试图用逆变

You should ignore the dynamic part here - it's a red herring. 您应该在这里忽略dynamic部分-这是一条红色鲱鱼。 Try working out some code you'd expect to work that doesn't use dynamic . 尝试编写一些您期望使用的代码,这些代码不使用dynamic Here's an example of why IDictionary<,> is invariant: 这是为什么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. IDictionary<TKey,TValue> does not support any variance. IDictionary<TKey,TValue>不支持任何差异。
    Imagine what would happen if you could convert IDictionary<string,object> to IDictionary<string,int> : 想象一下,如果将IDictionary<string,object>转换为IDictionary<string,int>会发生什么:
    Your interface now guarantees that every value it returns is an int . 现在,您的接口保证返回的每个值都是一个int But since you can add arbitrary objects to it, it can't actually ensure that guarantee. 但是由于您可以向其中添加任意对象,因此它实际上不能确保这一保证。
  2. Even interfaces which support variance, only support it between reference types. 即使支持方差的接口也仅支持引用类型之间的方差。 int is no reference type. int是没有引用类型。
  3. This issue is unrelated to dynamic. 此问题与动态无关。 You can't convert a class that only implements IDictionary<string,object> to IDictionary<string,int> . 您不能将仅实现IDictionary<string,object>的类转换为IDictionary<string,int> No matter if you use static casting or dynamic. 无论使用静态铸造还是动态铸造。 It simply doesn't implement that interface. 它根本没有实现该接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM