IList <IWhatever>в качестве параметра метода - PullRequest
2 голосов
/ 01 августа 2009

У меня есть два IList<ICat>, и я пытаюсь создать метод, который принимает IList<ICat> и выполняет некоторую работу. У меня возникают проблемы при попытке передать ему либо IList<PussyCat>, либо IList<OtherCat>, либо PussyCat, либо OtherCat реализуют ICat.

Я пробовал:

List<PussyCat> cats = ...
DoWork((IList<ICat>)cats);

и просто

DoWork(cats);

Но ни скомпилировать. Есть идеи?

Ответы [ 4 ]

7 голосов
/ 01 августа 2009

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.

Массивы, с другой стороны, ковариантны. Вы можете передать string[] методу, который ожидает object[].

5 голосов
/ 01 августа 2009

Есть две альтернативы:

  1. Сделайте ваш метод следующим образом:

    public void DoWork< T > (IList< T > cats_) where T : ICat
    {
        //Do work;
    }
    
  2. Другая возможность - использовать метод, подобный

    public void DoWork(IList< ICat > cats_) 
    {
        //Do work;
    }
    

    и назовите его следующим образом:

    {
        //....Assuming: IList<PussyCat> iListOfPussyCats
        List<PussyCat> pussyCats = new List<PussyCats>(iListOfPussyCats);
        DoWork(pussyCats.ConvertAll<ICat>( c => c as ICat);
    }
    
1 голос
/ 01 августа 2009

Если метод действительно не требует прямой индексации (IList<T>) и не требует добавления / удаления элементов (ICollection<T>), тогда передайте IEnumerable<T>. Методы расширения Cast<T>() позволяют передавать любой IList типа [insert ICat -точка] как IEnumerable<ICat>.

0 голосов
/ 01 августа 2009

До C # 4.0 прибывает, который имеет поддержку против и против дисперсии, вы могли бы уйти с чем-то вроде этого:

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>);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...