[英]IList<IWhatever> as a method parameter
I have two IList<ICat>
and I'm trying to create a method which takes an IList<ICat>
and does some work. 我有两个IList<ICat>
,我正在尝试创建一个方法,它采用IList<ICat>
并做一些工作。 I'm having problems trying to pass either an IList<PussyCat>
or IList<OtherCat>
to it, both PussyCat
and OtherCat
implement ICat
. 我在尝试将IList<PussyCat>
或IList<OtherCat>
传递给它时PussyCat
问题, PussyCat
和OtherCat
实现了ICat
。
I've tried: 我试过了:
List<PussyCat> cats = ...
DoWork((IList<ICat>)cats);
and just 只是
DoWork(cats);
But neither compile. 但是没有编译。 Any ideas? 有任何想法吗?
C# generics are invariant. C#泛型是不变的。 It means List<string>
is not a List<object>
. 这意味着List<string>
不是List<object>
。
C# 4.0 introduces safe covariance/contravariance but still, you wouldn't be able to pass List<string>
as List<object>
. C#4.0引入了安全协方差/逆变,但仍然无法将List<string>
作为List<object>
传递。 The reason is: 原因是:
List<string> x = new List<string>();
List<object> o = x; // assume this statement is valid
o.Add(5); // Adding an integer to a list of strings. Unsafe. Will throw.
Arrays, on the other hand are covariant. 另一方面,数组是协变的。 You can pass a string[]
to a method that expects object[]
. 您可以将string[]
传递给期望object[]
。
There are two alternatives: 有两种选择:
Make your method like this: 使你的方法像这样:
public void DoWork< T > (IList< T > cats_) where T : ICat { //Do work; }
The other possibility is to have a method like 另一种可能性是有一个方法
public void DoWork(IList< ICat > cats_) { //Do work; }
and call it in the following manner: 并按以下方式调用它:
{ //....Assuming: IList<PussyCat> iListOfPussyCats List<PussyCat> pussyCats = new List<PussyCats>(iListOfPussyCats); DoWork(pussyCats.ConvertAll<ICat>( c => c as ICat); }
If the method doesn't truly require direct indexing ( IList<T>
) and doesn't require adding/removing items ( ICollection<T>
), then pass an IEnumerable<T>
. 如果该方法不真正需要直接索引( IList<T>
)并且不需要添加/删除项( ICollection<T>
),则传递IEnumerable<T>
。 The Cast<T>()
extension methods allow casting any IList
of [insert ICat
-derived type] to be passed as an IEnumerable<ICat>
. Cast<T>()
扩展方法允许将[insert ICat
-derived type]的任何IList
转换为IEnumerable<ICat>
。
Till C# 4.0 arrives which has support for co and contra variance you might be able to get away with something like this: 直到C#4.0到达,它支持co和contra变化,你可能会得到这样的东西:
public void DoWork(IEnumerable<ICat> cats)
{
//do something
}
List<PussyCat> pussyCats = new List<PussyCat>;
List<OtherCat> otherCats = new List<OtherCat>;
DoWork(pussyCats.OfType<ICat>);
DoWork(otherCats.OfType<ICat>);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.