I have class where the relevant part looks like
class C {
void Method<T>(SomeClass<T> obj) {
list.Add(obj);
}
List<?> list = new List<?>();
}
How should I define the list so that the class compiles?
I want a list of type List<SomeClass<?>>
, that is a list of objects of SomeClass
where each object can have any type parameter. The Java ?
construct allows this; what is the C# equivalent? If no such thing exists, is there a suitable workaround? (A List<object>
would do but is terribly ugly.)
To do what you want, you have two options. You can use List<object>, and handle objects. This will not be typesafe, and will have boxing/unboxing issues for value types, but it will work. Your other option is to use a generic constraint to limit to a base class or interface, and use a List<Interface>.
The principle difference is that a generic type has a list of Type objects representing its generic type parameters. The first procedure in this section examines generic types. You can create a Type object that represents a constructed type by binding type arguments to the type parameters of a generic type definition.
Yes, There are two level where you can apply generic type . You can apply generic type on Method level as well as Class level (both are optional). As above example you applied generic type at method level so, you must apply generic on method return type and method name as well. You need to change a bit of code.
A generic in C# is a type that uses objects of a different type. Said different type is not specified until an instance of the generic object is created. We can identify a generic type by looking for the syntax <T> , where T is a placeholder that represents the type being used by the generic.
I don't think you can do this in C#... you would have to add the type parameter to the class:
class C<T> {
void Method(SomeClass<T> obj) {
list.Add(obj);
}
List<SomeClass<T>> list = new List<SomeClass<T>>();
}
The other option would be to use an interface:
class C {
void Method<T>(T obj)
where T : ISomeClass {
list.Add(obj);
}
List<ISomeClass> list = new List<ISomeClass>();
}
To do what you want, you have two options.
You can use List<object>, and handle objects. This will not be typesafe, and will have boxing/unboxing issues for value types, but it will work.
Your other option is to use a generic constraint to limit to a base class or interface, and use a List<Interface>.
Unfortunately, there is no direct equivalent in C# 3.0 as generics are invariant.
You'll be able to do something like this in a graceful manner using C# 4.0 safe co/contra-variance feature.
To workaround it, you could inherit SomeClass<T>
from a nongeneric base and create a List<BaseClass>
instead.
If each instance of the class should hold only one type, you could make the class itself generic and set the type parameter there.
I don't know anything about Java's ?
construct, but I think the following most closely preserves your existing syntax while also matching your description.
class SomeClass<T>
{
}
class C
{
void Add<T>(SomeClass<T> item)
{
Type type = typeof(SomeClass<T>);
if (!list.ContainsKey(type))
list[type] = new List<SomeClass<T>>();
var l = (List<SomeClass<T>>)list[type];
l.Add(item);
}
public void Method<T>(SomeClass<T> obj)
{
Add(obj);
}
readonly Dictionary<Type, object> list = new Dictionary<Type, object>();
}
test it with the following:
class Program
{
static void Main(string[] args)
{
var c = new C();
var sc1 = new SomeClass<int>();
var sc2 = new SomeClass<String>();
c.Method(sc1);
c.Method(sc2);
c.Method(sc1);
c.Method(sc2);
}
}
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