IList <IWhatever>作为方法参数

Ech*_*lon 2 c# generics interface

我有两个IList<ICat>,我正在尝试创建一个方法,它需要IList<ICat>一些工作.我试图传递一个IList<PussyCat>IList<OtherCat>两个,PussyCat并且OtherCat实现,我遇到了问题ICat.

我试过了:

List<PussyCat> cats = ...
DoWork((IList<ICat>)cats);
Run Code Online (Sandbox Code Playgroud)

只是

DoWork(cats);
Run Code Online (Sandbox Code Playgroud)

但是没有编译.有任何想法吗?

Meh*_*ari 7

C#泛型是不变的.这意味着List<string>不是List<object>.

C#4.0引入了安全协方差/逆变但尽管如此,你将无法通过List<string>List<object>.原因是:

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.
Run Code Online (Sandbox Code Playgroud)

另一方面,数组是协变的.您可以将a传递string[]给期望的方法object[].

  • 请注意,如果`DoWork`只是'foreach`集合而不改变任何东西,你可以将参数声明为`IEnumerable <ICat>`并用`DoWork(cats.Cast <ICat>())`来调用它. (3认同)

小智 5

有两种选择:

  1. 使你的方法像这样:

    public void DoWork< T > (IList< T > cats_) where T : ICat
    {
        //Do work;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 另一种可能性是有一个方法

    public void DoWork(IList< ICat > cats_) 
    {
        //Do work;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    并按以下方式调用它:

    {
        //....Assuming: IList<PussyCat> iListOfPussyCats
        List<PussyCat> pussyCats = new List<PussyCats>(iListOfPussyCats);
        DoWork(pussyCats.ConvertAll<ICat>( c => c as ICat);
    }
    
    Run Code Online (Sandbox Code Playgroud)