2010-01-11 3 views
6

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

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

Любые предложения?

ответ

4

Можно, конечно, объявить:

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

и

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

    foo.GetData<string>();

Это хорошо для вас?

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

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

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

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

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

+0

Я пробовал неосновный базовый класс, но он теряет деталь свойства Value – benPearce

+0

@benPearce: Но вы все равно не можете использовать это, потому что вы не знаете, какой тип. Попробуйте показать, как вы будете использовать код, а затем мы можем вам посоветовать лучше. –

+0

В итоге я опустился на базовый базовый интерфейс с объектами GetValue() и SetValue (object). Работает до сих пор – benPearce

3

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

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>(); 
    } 
} 
Смежные вопросы