10

I'm aware that C# doesn't have generic wildcards, and that a similar effect can be achieved by generic methods, but I need to use a wildcard in a field and can't work out if there is any way to encode it.

List<State<Thing>> list; void AddToList<T>() where T : Thing { list.Add(new State<T>()); } 

Of course, this doesn't work because the object being added isn't of type State<Thing>, it's of type State<T> where T : Thing. Is it possible to adjust the most internal type of the list to be the Java equivalent of ? extends Thing rather than just Thing?

3
  • 1
    Can you declare your list as List<State<T>> where T : Thing? Commented Dec 8, 2011 at 7:17
  • @abatishchev: maybe post it as an answer? Commented Dec 8, 2011 at 8:46
  • @konrad: Done Commented Dec 8, 2011 at 9:27

3 Answers 3

4

Note that C# 4 does have additional variance support, but it does not apply in the List<T> case, for various reasons (has both "in" and "out" methods, and is a class).

I think, however, the way to address this is with something like:

interface IState { // non-generic object Value { get; } // or whatever `State<Thing>` needs } class State<T> : IState { public T Value { get { ...} } // or whatever object IState.Value { get { return Value; } } } 

and

List<IState> list; ... 

which will then allow you to add any State<T>. It doesn't really use much of the T, and a cast would be needed to get from the object to T, but .... it will at least work.

Sign up to request clarification or add additional context in comments.

2 Comments

I really don't understand why can't I cast as the following: (State<Thing>)new State<T> while T : Thing! But can (Thing)new T()
@abatishchev because a SomeSpecificThing is a Thing; but it is not true that a State<SomeSpecificThing> is a State<Thing>. There is no inheritance etc. If it were a generic interface, if could potentially be IState<out Thing>, in which case the 4.0 variance rules start to apply, and then yes, there is a cast from IState<SomeSpecificThing> to IState<Thing>.
3

You could try something like this :

 interface IState<out T> { } class State<T> : IState<T> { } class Thing {} List<IState<Thing>> list; void AddToList<T>() where T : Thing { list.Add(new State<T>()); } 

1 Comment

I would prefer this, but I can't use C# 4.
0

Declare your list as the following:

class State<T> where T : Thing { ... List<State<T>> list = new List<State<T>>(); // or public class StateList<T> : List<State<T>> { void AddToList(T item); } } 

then compiler will be able to convert.

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.