tags:

views:

860

answers:

5
public void Getrecords(ref IList iList,T dataItem) 
{ 
  iList = Populate.GetList<dataItem>() // GetListis defined as GetList<T>
}

dataItem can be my order object or user object which will be decided at run time.The above does not work as it gives me this error The type 'T' must have a public parameterless constructor in order to use it as parameter 'T' in the generic type

A: 

You can use Generic with < T > that will accept the type in runtime like you want.

Daok
A: 
Getrecords<T> ...

This should have any more detailed information that you need. http://msdn.microsoft.com/en-us/library/twcad0zb(VS.80).aspx

Ryan Lanciaux
+2  A: 
public void GetRecords<T>(ref IList<T> iList, T dataitem)
{
}

What more are you looking for?

To Revised question:

 iList = Populate.GetList<dataItem>()

"dataitem" is a variable. You want to specify a type there:

 iList = Populate.GetList<T>()

The type 'T' must have a public parameterless constructor in order to use it as parameter 'T' in the generic type GetList:new()

This is saying that when you defined Populate.GetList(), you declared it like this:

IList<T> GetList<T>() where T: new() 
{...}

That tells the compiler that GetList can only use types that have a public parameterless constructor. You use T to create a GetList method in GetRecords (T refers to different types here), you have to put the same limitation on it:

public void GetRecords<T>(ref IList<T> iList, T dataitem) where T: new() 
{
   iList = Populate.GetList<T>();
}
James Curran
Thanks James for that detailed information
+3  A: 

Your revised question passes in dataItem as an object of type T and then tries to use it as a type argument to GetList(). Perhaps you pass dataItem in only as a way to specify T?

If so, the you may want something like so:

public IList<T> GetRecords<T>() {
  return Populate.GetList<T>();
}

Then you call that like so:

IList<int> result = GetRecords<int>();
David Alpert
I tried that and I get this The type 'T' must have a public parameterless constructor in order to use it as parameter 'T' in the generic typeGetList<T>:new()
If you need to be able to create a new one, specify T: object
Chris Marasti-Georg
Or, you can use default(T) to create a new instance as well.
Chris Marasti-Georg
where T : new() is what the compiler wants
Will
I thought this was what he wanted for a while, too, and then I realized he probably already has an object of some type that he wants to use to determine the type parameter to the method. Even so, this is still probably the right way to go. Just use MyDataItem.GetType() for the type parameter.
Joel Coehoorn
Hmm... except you can't do that.
Joel Coehoorn
to my knowledge, c# generics are executed as a compiler trick to achieve the static typing. If jon b truly needs run-time generic typing, perhaps the DLR will help.
David Alpert
@Joel - yes you can; via MakeGenericMethod (see pots)
Marc Gravell
@David - no, generics are a core part of the CLR v2; the compiler doesn't do any real tricks here; in fact, generics in C# follow static typing rules (everything done in C# < 4.0 is static typed)
Marc Gravell
A: 

The issue with demanding a public, parameterless constructor can only be because Populate.GetList demands it - i.e. has the "T : new()" constraint. To fix this, simply add the same constraint to your method.

Actually, I doubt that ref is a good strategy here. At a push, out might do (since you don't read the value), but a far simpler (and more expected) option is a return value:

public IList<T> GetRecords<T>(T dataItem) where T : new()
{  // MG: what does dataItem do here???
  return Populate.GetList<T>();
}

Of course, at that point, the caller might as well just call Populate.GetList directly!

I suspect you can remove dataItem too... but it isn't entirely clear from the question.

If you don't intend it to be generic (and dataItem is the template object), then you can do this via MakeGenericMethod:

public static IList GetRecords(object dataItem) 
{
    Type type = dataItem.GetType();
    return (IList) typeof(Populate).GetMethod("GetList")
        .MakeGenericMethod(type).Invoke(null,null);
}
Marc Gravell
MG: If i have a order object then the list will be collection of order objects and it helps me avoid building my own strongly typed collection inheriting from collection base and looping through a dataset and building the collection so I can pass the custom collection around instead of a dataset