Reputation: 818
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?
Upvotes: 7
Views: 7338
Reputation: 144206
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))
}
Upvotes: 12
Reputation: 9203
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.
Upvotes: 1
Reputation: 564811
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);
Upvotes: 7