views:

244

answers:

5

Running .NET 2.0, I have a generic method with the following signature:

static listType FillCollection<listType, objType>(IDataReader dr) where listType : ICollection<objType>, new()

it's purposes is to translate a datareader into a collection of objects both of my choosing. My problem, which isn't exactly a problem, is that when I call it, the call ends up looking something like this:

List<MyObject> data = FillCollection<List<MyObject>, MyObject>(dr);

I'm curious if there's a way to cut out the redundancy of having to specify MyObject twice in the call. Ideally, I'd be able to only specify it once, along with the collection type and maintain the strong typed nature of the method. Adding another wrapper method to abstract the ICollection type sorta does the trick:

List<MyObject> data = FillList<MyObject>(dr);

static List<objType> FillList<objType>(dr)
{
    return FillCollection<List<objType>, objType>(dr);
}

But I'd rather not have a wrapper method for every collection i want to use.

Maybe I have no choice in the matter, but if so, I don't have to like it! ;)

Thanks!

A: 

If you use Visual Studio 2008, you can still target .NET 2.0, but use C# 3.0 syntax. This means you can use the "var" keyword:

var data = FillCollection<List<MyObject>, MyObject>(dr);

When you're using Visual Studio 2005, you're out luck I'm afraid.

Philippe Leybaert
I think he wanted to avoid specifying MyObject twice in the method call, like you're still doing. I could be wrong though.
Lasse V. Karlsen
Hmmm... I didn't read it like that. But there's only one person who can help us out. Wes? What did you mean?
Philippe Leybaert
Lasse's correct, that was what I was trying to avoid.But I'm still on VS2005, so no var.
Wes P
A: 

Could you use var?

+2  A: 

This might be something worth trying:

static listType FillCollection<objType>(IDataReader dr, ICollection<objType> list)

This would let you call it without specifying the type twice, but you'd be forced to create the collection outside of FillCollection.

var list = new List<MyObject>();
var data = FillCollection<MyObject>(dr, list);

Probably not what you were hoping for since you still refer to MyObject twice (once in the creation of the List and another in the FillCollection), but I don't think you're going to be able to get away from that without losing strong typing.

Joseph
+1  A: 

Personally, I'm not really sure why you need your method to be able to create multiple different implementations of ICollection. My inclination would be to have a method signature as follows, and just create a List inside the method and return it.

static ICollection<T> FillCollection<T>(IDataReader dr) where T : class, new()

If that's not acceptable, then I'd go with Joseph's answer.

Joel Mueller
+1  A: 

Sort of going off of what Joseph mentioned, I've used "out" parameters in the past with good results, but never with one generic type relying on another one without taking or returning a value of that type. Anyway, you could do something like this, though you'd have to have a list of objTypes and a single object of objType declared outside of the call to FillCollection, and FillCollection would become void. Here's what it would look like, but whether or not it's a good idea to increase readability is up to you.

public static void FillCollection<listType, objType>(IDataReader dr, out listType collection, out objType obj) 
    where listType : ICollection<objType>, new() 
    where objType : new()
{
    collection = new listType();
    obj = new objType();

    // Do whatever you do to fill the collection
}

public static void TestFillCollection()
{
    IDataReader dr;
    List<MyObject> myObjects;
    MyObject myObject;

    FillCollection(dr, out myObjects, out myObject);
}
Chris Doggett