8

I have a question involving calling a class's generic method with a type parameter that is known at runtime.

In specific, the code looks like so:


FieldInfo[] dataFields = this.GetType().GetFields( BindingFlags.Public | BindingFlags.Instance );

// data is just a byte array used internally in DataStream
DataStream ds = new DataStream( data );

foreach ( FieldInfo field in dataFields )
{
    Type fieldType = field.FieldType;

    // I want to call this method and pass in the type parameter specified by the field's type
    object objData = ( object ) ds.Read<fieldType>();
}

The Read() function looks like so:


public T Read() where T : struct

This function's purpose is to return data read from a byte array.

Is there any way to call a generic method at runtime like this?

Ryan Stecker
  • 828
  • 13
  • 25

3 Answers3

12

The easiest way to handle this would be to make a non-generic overload of the Read function with a single Type parameter:

public object Read(Type t)

And then have the generic version call the non-generic version:

public T Read<T>() where T : struct
{
    return (T)Read(typeof(T))
}
Lee
  • 142,018
  • 20
  • 234
  • 287
7

You'll need to build a methodinfo and invoke the Read method:

MethodInfo method = typeof(DataStream).GetMethod("Read");
MethodInfo generic = method.MakeGenericMethod(fieldType);
object objData = generic.Invoke(ds, null);
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
1

It would probably be better to go Lee's route. Generic's are shorthand at design-time to keep you from having to write common code for many different types of classes. At compile time every call to a generic method or class is basically generated as a completely separate class.

Much simpler to just bass the the type and use reflection, which is what you would have to do anyways.

Nick
  • 9,113
  • 4
  • 25
  • 29
  • True, Lee's method would also be better performance-wise, as the additional reflection to retrieve the MethodInfo would be additional computation that could be avoided with his method. – Ryan Stecker Sep 21 '09 at 18:27