Общий список универсальных интерфейсов не допускается, альтернативные подходы? - PullRequest
22 голосов
/ 24 декабря 2010

Я пытаюсь найти правильный способ использования универсального списка универсальных интерфейсов в качестве переменной.

Вот пример. Это, вероятно, не самый лучший, но, надеюсь, вы поймете:

public interface IPrimitive<T>
{
     T Value { get; }
}

, а затем в другом классе я хочу иметь возможность объявить переменную, которая содержит список объектов, которые реализуют IPrimitive<T> для произвольного T.

// I know this line will not compile because I do not define T   
List<IPrimitive<T>> primitives = new List<IPrimitives<T>>;

primitives.Add(new Star());   // Assuming Star implements IPrimitive<X>
primitives.Add(new Sun());    // Assuming Sun implements IPrimitive<Y>

Обратите внимание, что T в IPrimitive<T> может отличаться для каждой записи в списке.

Любые идеи о том, как я мог бы установить такие отношения? Альтернативные подходы?

Ответы [ 3 ]

24 голосов
/ 24 декабря 2010
public interface IPrimitive
{

}

public interface IPrimitive<T> : IPrimitive
{
     T Value { get; }
}

public class Star : IPrimitive<T> //must declare T here
{

}

Тогда вы должны иметь возможность

List<IPrimitive> primitives = new List<IPrimitive>;

primitives.Add(new Star());   // Assuming Star implements IPrimitive
primitives.Add(new Sun());    // Assuming Sun implements IPrimitive
10 голосов
/ 24 декабря 2010

Джон прав.

Могу ли я также предложить (если вы используете C # 4) сделать свой интерфейс ковариантным?

public interface IPrimitive<out T>
{
     T Value { get; }
}

Это может сэкономитьу вас возникают проблемы, когда вам нужно вычеркнуть вещи из списка.

4 голосов
/ 24 декабря 2010

Вы говорите, что это не сработает, потому что вы не определяете T. Так определите это:

public class Holder<T>
{
    public List<IPrimitive<T>> Primitives {get;set;}
}
...