Список универсальных интерфейсов - PullRequest
6 голосов
/ 12 января 2010

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

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() 

Есть предложения?

Ответы [ 2 ]

4 голосов
/ 12 января 2010

Можно, конечно, заявить:

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

и

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

    foo.GetData<string>();

Это нормально для тебя?

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

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

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

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

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

3 голосов
/ 12 января 2010

Нет, вы не можете сделать это - единственные варианты - использовать неуниверсальный интерфейс:

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>();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...