Есть ли шанс сыграть законно? - PullRequest
3 голосов
/ 24 февраля 2011

Я впервые задаю вопрос здесь, поэтому заранее спасибо всем, кто поможет мне (и, возможно, другим).

Сегодня я был озадачен ковариацией и контравариантностью в C # 4, но я действительно не вижу возможности сделать то, что сделал бы я. ПРИМЕЧАНИЕ: все это НЕ для решения конкретной проблемы, но я хотел бы знать, есть ли какой-нибудь законный способ (совершенно новая комбинация / противоречие в C # 4) для ее решения. Так что, не сходи с ума ...

Вот пример кода:

public interface IBase<in T>
{
    T GetValue();
    ...
}


public class Readable<T> : IBase<T>
{
    public T GetValue() {/* */}
    ...
}


public class Writeable<T> : IBase<T>
{
    public T GetValue() {/* */}
    public void SetValue(T value) {/* */}
    ...
}


public class Program
{
    private List<IBase<object>> _collection = new List<IBase<object>>();


    public static void Main()
    {
        var p = new Program();

        p._collection.Add(new Readable<bool>());    //not allowed
    }
}

Коллекция должна содержать любые производные IBase, являющиеся ими любого T. Конечно, я могу использовать неуниверсальную коллекцию или Список, и игра окончена. Другая идея - иметь более общий интерфейс IBaseCore, чем IBase наследуется от. Мой вопрос: без этих уловок я могу добиться, чтобы иметь коллекцию IBase и добавлять элементы любого IBase?

Спасибо всем.

1 Ответ

3 голосов
/ 24 февраля 2011

РЕДАКТИРОВАТЬ: Во-первых, во-первых, ваше отклонение неправильно для IBase<T>. Он должен быть out T (ковариантный), а не in T (контравариантный).

Проблема здесь в том, что общая ковариация и контравариантность не работают с типами значений в качестве аргументов типа. Таким образом, вы можете добавить Readable<string>, но не Readable<bool>.

Один из вариантов - использовать неуниверсальный базовый интерфейс:

public interface IBase
{
    object GetValueAsObject();
}

public interface IBase<out T> : IBase
{
    T GetValue();
    ...
}

Тогда вы могли бы иметь List<IBase>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...