Wildcard equivalent in C# generics
Solution 1:
Generics in C# make stronger guarantees than generics in Java. Therefore, to do what you want in C#, you have to let the GeneralPropertyMap<T>
class inherit from a non-generic version of that class (or interface).
public class GeneralPropertyMap<T> : GeneralPropertyMap
{
}
public class GeneralPropertyMap
{
// Only you can implement it:
internal GeneralPropertyMap() { }
}
Now you can do:
private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps)
{
}
And:
GeneralPropertyMap[] maps = new GeneralPropertyMap[3];
maps[0] = new GeneralPropertyMap<String>();
maps[1] = new GeneralPropertyMap<Integer>();
maps[2] = new GeneralPropertyMap<Double>();
TakeGeneralPropertyMap(maps);
Solution 2:
While, as others have noted, there's no exact correspondence to wildcards in c#, some of their use cases can be covered with covariance/contravariance.
public interface IGeneralPropertyMap<out T> {} // a class can't be covariant, so
// we need to introduce an interface...
public class GeneralPropertyMap<T> : IGeneralPropertyMap<T> {} // .. and have our class
// inherit from it
//now our method becomes something like
private void TakeGeneralPropertyMap<T>(IList<IGeneralPropertyMap<T>> maps){}
// and you can do
var maps = new List<IGeneralPropertyMap<Object>> {
new GeneralPropertyMap<String>(),
new GeneralPropertyMap<Regex>()
};
//And finally pass the array in.
TakeGeneralPropertyMap<Object>(maps);
The caveat is that you can't use covariance with value types, so adding a new GeneralPropertyMap<int>()
to our list fails at compile time.
cannot convert from 'GeneralPropertyMap<int>' to 'IGeneralPropertyMap<object>'
This approach may be more convenient than having a non-generic version of your classes/interfaces in case you want to constrain the types that GeneralPropertyMap
can contain. In that case:
public interface IMyType {}
public class A : IMyType {}
public class B : IMyType {}
public class C : IMyType {}
public interface IGeneralPropertyMap<out T> where T : IMyType {}
allows you to have:
var maps = new List<IGeneralPropertyMap<IMyType>> {
new GeneralPropertyMap<A>(),
new GeneralPropertyMap<B>() ,
new GeneralPropertyMap<C>()
};
TakeGeneralPropertyMap(maps);