List of generic interfaces

You can certainly declare:

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

and

public IDataElement<object>[] GetData()
  • although the latter probably isn't what you're after (your interface won't be variant even in C# 4 as it uses T in both an input and an output position; even if it were variant, you wouldn't be able to use that variance for value types). The former will require the caller to specify <T>, e.g.

    foo.GetData<string>();

Is that okay for you?

There's no way of expressing "a collection of object, each of which implements IDataElement<T> for a different T" unless you also give it a nongeneric base class, at which you could just use IList<IDataElement>. In this case the nongeneric IDataElement could have the DataElement property, leaving the Value property in the generic interface:

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

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

Is that useful in your particular situation?

It's not clear how you'd want to use a collection of data elements without knowing their types... if the above doesn't help you, maybe you could say more about what you expected to do with the collections.


No you can't do this - the only options are to either use a non-generic interface:

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

Alternatively create a wrapper and pass that to methods that know the types they require:

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