IList использование ковариантности и контравариантности в c#, действительно ли это возможно?

Что я делаю для абстрактных классов, и интерфейсы следующее: Я пишу тест, который использует объект, поскольку это конкретно. Но переменная типа X (X абстрактный класс) не установлена в тесте. Этот тестовый класс не добавляется к набору тестов, но подклассам его, которые имеют метод установки, которые устанавливают переменную на конкретную реализацию X. Тем путем я не копирую тестовый код. Подклассы не используемого теста могут добавить больше методов тестирования в случае необходимости.

6
задан skaffman 11 August 2009 в 08:51
поделиться

2 ответа

Нет, нельзя. В вашем примере IList инвариантен. IList потребует объявить in / out как ковариантный / контравариантный. Это невозможно сделать, просто унаследовав какой-то ковариантный интерфейс.

5
ответ дан 8 December 2019 в 18:39
поделиться

Что ж, ваш вопрос немного сбивает с толку из-за существующего типа IList . Однако следующий компилирует :

public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
    IEnumerator<TOutput> GetEnumerator();
    void Add(TInput item);
}

public interface ISimpleList<T> : IComplexList<T, T>
{
}

Вы даже можете изменить его, чтобы расширить IEnumerable :

public interface IComplexList<out TOutput, in TInput>
    : IEnumerable<TOutput>
    where TOutput : TInput
{        
    void Add(TInput item);
}

public interface ISimpleList<T> : IComplexList<T, T>
{
}

Индексатор сложен, потому что вы хотите задействовать разные типы . Вы можете сделать:

TOutput Get(int index);
void Set(int index, TInput item);

, а затем поместить индексатор в ISimpleList вместо того, конечно ...

Это не позволяет вам использовать ISimpleList как вариант хотя, поскольку вы в основном принудительно использовали TInput = TOutput.

Альтернативный подход состоит в том, чтобы отделить ввод от вывода:

public interface IReadableList<out T> : IEnumerable<T>
{
    T Get(int index);
}

public interface IWritableList<in T>
{
    void Add(T item);
    void Set(int index, T item);
}

 public interface IMyList<T> : IReadableList<T>, IWritableList<T> {}

Затем вы можете написать:

public void Foo(IWritableList<string> x) { ... }

IMyList<object> objects = new MyList<object>();
Foo(objects);

и наоборот для IReadableList . Другими словами,

8
ответ дан 8 December 2019 в 18:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: