I can create a generic class that takes, as its template parameter, a C# type, and then within the generic class use the System.Type information corresponding to that C# type:
public class Generic<T>
{
public bool IsArray()
{
return typeof(T).IsArray();
}
public T Create()
{
return blah();
}
}
Generic<int> gi = new Generic<int>();
Debug.WriteLine("int isarray=" + gi.IsArray());
Generic<DateTime> gdt;
But now let's say what I have, is a System.Type. I can't use this to instantiate my generic class:
FieldInfo field = foo();
Generic<field.FieldType> g; // Not valid!
Is there some clever C# thing I can do, to convert a System.Type back to the original C# type? Or some other way, to create a generic that can (1) give me information about the System.Type, and (2) create objects of the associate C# type?
By the way, this is a very contrived example to explain the problem I'm trying to solve, don't worry too much about whether Generic makes sense or not!
The only thing you can do is use reflection. This because while the int
of Generic<int>
is known at compile-time, the field.FieldType
is known only at runtime.
Reflection example:
Type type = typeof(Generic<>).MakeGenericType(field.FieldType);
// Object of type Generic<field.FieldType>
object gen = Activator.CreateInstance(type);
But even here, from a Type
(field.FieldType
) you obtain another Type
(type
)
There are normally three ways of using this:
Generic<type>
only through reflection. You create it through Activator.CreateInstance
and from there you begin using Type.GetMethod()
and Invoke()
Type type = typeof(Generic<>).MakeGenericType(field.FieldType);
// Object of type Generic<field.FieldType>
object gen = Activator.CreateInstance(type);
MethodInfo isArray = type.GetMethod("IsArray");
bool result = (bool)isArray.Invoke(gen, null);
Generic<T>
. You use your object only though that interface/base class.public class Generic<T> : IComparable where T : new()
{
public bool IsArray()
{
return typeof(T).IsArray;
}
public T Create()
{
return new T();
}
public int CompareTo(object obj)
{
return 0;
}
}
Type type = typeof(Generic<>).MakeGenericType(field.FieldType);
IComparable cmp = (IComparable)Activator.CreateInstance(type);
int res = cmp.CompareTo(cmp);
Generic<T>
. That is the only method that is used through reflection.public static void WorkWithT<T>() where T : new()
{
Generic<T> g = new Generic<T>();
T obj = g.Create();
Console.WriteLine(g.IsArray());
}
var method = typeof(Program).GetMethod("WorkWithT").MakeGenericMethod(field.FieldType);
// Single reflection use. Inside WorkWithT no reflection is used.
method.Invoke(null, null);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With