Список универсальных интерфейсов

Если у меня есть универсальный интерфейс с несколькими классами с реализацией, такими как:

public interface IDataElement<T>
{
    int DataElement { get; set; }
    T Value { get; set; }
}

public class IntegerDataElement : IDataElement<int>
{
    public int DataElement { get; set; }
    public int Value { get; set; }
}

public class StringDataElement : IDataElement<String>
{
    public int DataElement { get; set; }
    public String Value { get; set; }
}

Действительно ли возможно передать набор классов с реализацией отличающихся типов, не имея необходимость обращаться к передаче как объект.

Это, кажется, не возможно определить возвращаемые значения как

public IDataElement<T>[] GetData()

или

public IDataElement<object>[] GetData() 

Какие-либо предложения?

6
задан Joe 11 January 2010 в 21:37
поделиться

2 ответа

Вы, конечно, можете объявить:

public IDataElement<T>[] GetData<T>()

и

public IDataElement<object>[] GetData()
  • хотя последнее, вероятно, не то, что вам нужно (ваш интерфейс не будет вариантом даже в C# 4, так как он использует T как во входной, так и во выходной позиции; даже если бы он был вариантом, вы не смогли бы использовать эту дисперсию для типов значений). Первая потребует от вызывающего абонента указать , например,

    foo.GetData();

Это вас устраивает?

Нет способа выразить "коллекцию объектов, каждый из которых реализует IDataElement для другой T", если только вы также не дадите ему неэнергетический базовый класс, в котором вы можете просто использовать IList. В этом случае неэнергетический IDataElement может иметь свойство DataElement, оставляя свойство Value в общем интерфейсе:

public interface IDataElement
{
    int DataElement { get; set; }
}

public interface IDataElement<T> : IDataElement
{
    T Value { get; set; }
}

Это полезно в вашей конкретной ситуации?

Не ясно, как вы захотите использовать коллекцию элементов данных, не зная их типов... если вышесказанное не поможет вам, может быть, вы могли бы сказать больше о том, что вы ожидали сделать с этими коллекциями.

4
ответ дан 17 December 2019 в 00:10
поделиться

Нет, вы не можете это сделать - единственными вариантами являются либо использование нерегического интерфейса:

public interface IDataElement
{
    int DataElement { get; set; }
    object Value { get; set; }
}

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

public class DataElementBag
{
    private IDictionary<Type, List<object>> _elements;
    ...
    public void Add<T>(IDataElement<T> de)
    {
        Type t = typeof(T);
        if(!this._elements.ContainsKey(t))
        {
            this._elements[t] = new List<object>();
        }

        this._elements[t].Add(de);
    }

    public void IEnumerable<IDataElement<T>> GetElementsByType<T>()
    {
        Type t = typeof(T);
        return this._elements.ContainsKey(t)
            ? this._elements[t].Cast<IDataElement<T>>()
            : Enumerable.Empty<T>();
    }
}
3
ответ дан 17 December 2019 в 00:10
поделиться
Другие вопросы по тегам:

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