If I have a generic interface with a couple of implementing classes such as:
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; }
}
Is it possible to pass a collection of the implementing classes of differing types, without having to resort to passing as object.
It does not appear to be possible to define a return values as
public IDataElement<T>[] GetData()
or
public IDataElement<object>[] GetData()
Any suggestions?
Generic Interfaces in Java are the interfaces that deal with abstract data types. Interface help in the independent manipulation of java collections from representation details. They are used to achieving multiple inheritance in java forming hierarchies. They differ from the java class.
Declaring Variant Generic Interfaces You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.
The Generic List<T> Class in C# is a collection class that is present in System. Collections. Generic namespace. This Generic List<T> Collection Class represents a strongly typed list of objects which can be accessed by using the index.
Java Generic Interface In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example new HashMap<String, List<String>>(); is valid.
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>();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With