Приведите CustomList <CustomClass>к IList <Interface> - PullRequest
0 голосов
/ 13 июля 2010

(это .Net 3.5) У меня есть класс FooList, который реализует IList, и класс FooClass, который реализует IFoo. Пользователь требует IList<IFoo>. В моей реализации я создаю FooList<FooClass> с именем X. Как мне кодировать мой возврат, чтобы мой FooList<FooClass> X стал его IList<IFoo>?

Если я попытаюсь

return X.Cast () .ToList ();

он получает IList<IFoo>, но это не мой FooList; это список, и новый при этом.

1 Ответ

1 голос
/ 13 июля 2010

Это не сработает, потому что FooList<FooClass> - это не IList<IFoo>. Вот почему:

var myList = new FooList<FooClass>();
IFoo obj = new SomeOtherFooClass();
IList<IFoo> result = (IList<IFoo>)myList; // hypothetical, wouldn't actually work
result.Add(obj); // uh-oh, now myList has SomeOtherFooClass

Вам необходимо либо сделать копию, либо использовать интерфейс, который на самом деле является ковариантным для содержимого типа, например IEnumerable<T> вместо IList<T>. Или, если это уместно, вместо этого вы должны объявить FooList<FooClass> как FooList<IFoo> с самого начала.

Вот небольшая реализация, которая демонстрирует мое второе предложение:

public interface IFoo { }
public class FooClass : IFoo { }

public class FooList<T> : IList<T>
{
    public void RemoveAt(int index) { /* ... */ }
    /* further boring implementation of IList<T> goes here */
}

public static void ListConsumer(IList<IFoo> foos)
{
    foos.RemoveAt(0); // or whatever
}

public static IList<IFoo> ListProducer()
{
    // FooList<FooClass> foos = new FooList<FooClass>(); // would not work
    FooList<IFoo> foos = new FooList<IFoo>();

    foos.Add(new FooClass());

    return foos; // a FooList<IFoo> is an IList<IFoo> so this is cool
}

public static void Demo()
{
    ListConsumer(ListProducer()); // no problemo
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...