协方差和向上转换之间有什么区别,或者更具体地说,它们为什么被赋予不同的名称?
我已经看到以下示例称为"向上转换":
string s = "hello";
object o = s; //upcast to 'string' to 'object'
Run Code Online (Sandbox Code Playgroud)
然而,我见过以下所谓的'协方差':
string[] s = new string[100];
object[] o = s;
IEnumerable<string> ies = new List<string>();
IEnumerable<object> ieo = ies;
Run Code Online (Sandbox Code Playgroud)
现在,对于我未经训练的眼睛,协方差似乎与向上转换相同,除了它指的是集合的铸造.(关于逆变和向下转换,可以做出类似的陈述).
它真的那么简单吗?
信不信由你,我继续把这个界面整合到我开始的开源库中,Tao.NET.我写了一篇博客文章解释这个库的IArray<T>
界面,它不仅解决了我最初在这个问题中提出的问题(一年前?!),而且还提供了协变索引界面,这在BCL中非常缺乏(在我看来).
我问为什么.NET有IList<T>
,它实现ICollection<T>
,因此提供的方法来修改列表(Add
,Remove
,等),但不提供任何在两者之间的接口,如IArray<T>
提供通过索引没有任何列表修改随机访问.
在以乔恩斯基特原来的答案评论(其中他质疑多久人们就必须需要任何合同,如IArray<T>
),我提到Keys
和Values
该属性SortedList<TKey, TValues>
类是IList<TKey>
与IList<Value>
分别,到乔恩回答说:
但在这种情况下,它被声明为IList,你知道只使用索引器....它并不是非常优雅,我同意 - 但它实际上并没有给我带来任何痛苦.
这是合理的,但我会回答说它不会给你带来任何痛苦,因为你只知道你做不到.但你知道的原因并不是从代码中清楚地看出来; 这是你有经验的SortedList<TKey, TValue>
课程.
如果我这样做,Visual Studio不会给我任何警告:
SortedList<string, int> mySortedList = new SortedList<string, int>();
// ...
IList<string> keys = mySortedList.Keys;
keys.Add("newkey");
Run Code Online (Sandbox Code Playgroud)
据说这是合法的IList<string>
.但我们都知道,它会导致异常.
纪尧姆也提出了一个恰当的观点:
好吧,接口并不完美,但开发人员可以在调用Add/Remove/Set之前检查IsReadOnly属性...
再次,这是合理的,但是:这不会让你觉得有点迂回吗?
假设我定义了一个接口如下:
public interface ICanWalkAndRun …
Run Code Online (Sandbox Code Playgroud) .net ×2
c# ×2
casting ×1
collections ×1
covariance ×1
ilist ×1
interface ×1
invariants ×1
java ×1
readonly ×1