tags:

views:

265

answers:

3

Aloha

I have a method with (pseudo) signature:

public static T Parse<T>(string datadictionary) where T : List<U>

This doesn't build. How can I restrict the in the method to accept only generic List<> objects (which should of cource not contain T's but something else :)

I need to restrict the type of T because I need to call a method on it in this code. The type passed in is a custom collection (based on List).

public class MyCollection<T> : List<T> where T: MyClass, new()
{
    public void Foo();
}


public static T Parse<T>(string datadictionary) where T : MyCollection<U>
{
    T.Foo();
}

-Edoode

+8  A: 

Well, you can have two type parameters:

public static T Parse<T, U>(string datadictionary) where T : List<U>

That way you'll also actually know what U is (in a compile-time manner)...

EDIT: Alternatively (and better), just specify the element type and change the return type:

public static List<T> Parse<T>(string datadictionary)

e.g.

List<int> data = Parse<int>(whatever);

Note that you may wish to change from List<T> to IList<T> or even a broader interface.

Jon Skeet
Of course, this forces you to supply the same information twice: both the type argument for whatever descendant of List<U> that you supply as T, and again as U. So, it would be Parse<List<int>,int>, or Parse<List<string>,string>, etc., which seems redundant.
Barry Kelly
True. There's a better alternative. Adding now...
Jon Skeet
But as I read the question, the caller wants to specify a subclass of List<T> MYlist<int> data = Parse<Mylist<int>>(whatever)
Bjarke Ebert
Then they'd have to use the first form, and also specify a new() constraint on T so that it can actually be constructed. That's a pretty odd requirement though.
Jon Skeet
+3  A: 

Assuming I read the question correctly, and you want to return T where T : List<U> (for some T and U)...

As an aside - subclassing List<T> isn't usually very useful... List<T> doesn't provide any useful virtual methods. Subclassing Collection<T> provides more flexibility. Of course, you can make your code not care, by simply coding against the IList<T> interface, perhaps adding : new() so you can create the list itself:

public static TList Parse<TList, TItem>(string datadictionary)
    where TList : IList<TItem>, new() {...}
Marc Gravell
Thanks. Is it also possible to restrict TIitem in your example?
edosoft
@Edoode, sure - just add a second "where" - i.e. "where TItem : class, IFoo"
Marc Gravell
+2  A: 

You can also do this, without specifying a restriction of type List<u>

 public static List<T> Parse<T>(string datadictionary) ...
Pop Catalin