Reputation: 2400
I have a generic class that exposes a generic method. This method receives an instance of the generic object as parameter and modifies this instance.
Example class:
public class GenericClass<T>
{
public T GenericMethod(T obj)
{
// modify the object in some (arbitrary) way
IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
foreach (FieldInfo field in fields)
{
if (field.FieldType == typeof(string))
{
field.SetValue(obj, "This field's string value was modified");
}
}
return obj;
}
}
If I have a type (abc):
public class abc
{
public string a;
public string b;
public int c;
}
I can call this method as follows:
GenericClass<abc> myGeneric = new GenericClass<abc>();
var myObject = myGeneric.GenericMethod(new abc());
//Confirm success by printing one of the fields
Console.Writeline(((abc)myObject).a);
Now, my actual question:
How would I call this same Generic method, using a type that is only known at run-time (as opposed to type abc above). I also want to instantiate this this as I pass it in to the GenericMethod, just like I did for abc above.
E.g. (I know this is completely wrong)
Type MyType;
GenericClass<MyType> myGeneric = new GenericClass<MyType>();
var myObject = myGeneric.GenericMethod(new MyType());
Due to unknown type success cannot be confirmed by printing the field "a" which may not exist, I could print the value of all string fields, but this is beyond the scope of the question.
Upvotes: 1
Views: 7317
Reputation: 3446
To answer your question:
var type = typeof(abc);
object instanceToModify = new abc();
var typeToCreate = typeof(GenericClass<>).MakeGenericType(type);
var methodToCall = typeToCreate.GetMethod("GenericMethod");
var genericClassInstance = Activator.CreateInstance(typeToCreate);
methodToCall.Invoke(genericClassInstance, new[] { instanceToModify });
But:
If your type is only known at runtime your instance must be handled in a variable declared as object
or dynamic
. In that case you can change your method signature to:
public object GenericMethod(object obj)
{
// modify the object in some (arbitrary) way
IEnumerable<FieldInfo> fields = obj.GetType().GetRuntimeFields();
foreach (var field in fields)
{
if (field.FieldType == typeof(string))
{
field.SetValue(obj, "This field's string value was modified");
}
}
return obj;
}
There's no need for a generic class/method.
Upvotes: 1