13

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

3
  • can you please elaborate on the sort of items you would expect to add via the "Method" function? Commented Apr 16, 2009 at 0:53
  • ah nevermind, i see it in a comment. Commented Apr 16, 2009 at 0:55
  • In c# 4.0 you can declare SomeClass as dynamic and not use the generics. The list then becomes List<SomeClass>. Commented Mar 3, 2011 at 1:00

5 Answers 5

14

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>(); } 
Sign up to request clarification or add additional context in comments.

4 Comments

I think this gets more at the spirit of what i understand the questioner to be asking (the interface version). Basically its a list of "partially known" items, but more than just "List<object>"
Thanks for the help. So stackoverflow lets me edit my question...but is there any way to combine your answer with those below that add extra information about the impossibility of what I want in C#?
@errcw I can edit it, or anytone else with 2k+ rep can... what specific info did you want?
Simply the technical note on C# 3/4 from Mehrdad: "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."
3

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>.

Comments

2

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.

1 Comment

Thanks for the BaseClass tip, really useful indeed when you want to emulate Java wildcards.
2

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

Comments

0

Personally, I would do this where possible; move the generic parameter from the method, to the class.

class C<T> { void Method(SomeClass<T> obj) { list.Add(obj); } List<?> list = new List<?>(); } 

If your generic list is a member, it stands to reason that the class should be constructed with this in mind. It is hard for us to suggest the best pattern without more usage context for the class.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.