c# список интерфейсов с универсальными элементами


Мой вопрос несколько похож на Общий список общих интерфейсов не допускается, какие-либо альтернативные подходы?

Если у меня есть интерфейс, такой как

public interface IPrimitive
{

}

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

public class Star : IPrimitive<string> //must declare T here
{
    public string Value { get { return "foobar"; } }
}

public class Sun : IPrimitive<int>
{
    public int Value { get { return 0; } }
}

Тогда у меня есть список

var myList = new List<IPrimitive>();
myList.Add(new Star());
myList.Add(new Sun());

При циклическом просмотре этого списка, как я могу получить свойство Value?

foreach (var item in myList)
{
    var value = item.Value; // Value is not defined in IPrimitive so it doesn't know what it is
}

Я не уверен, как это возможно.

Спасибо, Роб

4 2

4 ответа:

Вы можете воспользоваться динамический:

foreach (dynamic item in myList) 
{ 
    var value = item.Value; 
} 

Динамический тип позволяет операциям, в которых он происходит, обойти проверку типов во время компиляции. Вместо этого эти операции разрешаются во время выполнения

Вы могли бы сделать что-то вроде этого:

public interface IPrimitive
{
    object Value { get; }
}

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

public class Star : IPrimitive<string> //must declare T here
{
    public string Value { get { return "foobar"; } }
    object IPrimitive.Value { get { return this.Value; } }
}

public class Sun : IPrimitive<int>
{
    public int Value { get { return 0; } }
    object IPrimitive.Value { get { return this.Value; } }
}

Тогда вы можете получить значение как объект, когда у вас есть только IPrimitive.

Конечно, нет, ваше значение будет иметь разные типы..... поэтому вам придется опуститься до реального типа, чтобы получить различные значения.

В основном ваш интерфейс не работает. Это не "общий интерфейс", это скорее"подобный интерфейс"

Если вы не хотите делать кастинг, то вам придется найти интерфейс, который является общим для них обоих.

Вы можете переместить свойство Value в базовый интерфейс.

public interface IPrimitive
{
     object Value { get; }
}

Как вы хотите, чтобы procced value в цикле он имеет другой тип?