我可以创建一个泛型类,它将C#类型作为模板参数,然后在泛型类中使用与该C#类型对应的System.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;
Run Code Online (Sandbox Code Playgroud)
但现在让我们说我拥有的是System.Type.我无法使用它来实例化我的泛型类:
FieldInfo field = foo();
Generic<field.FieldType> g; // Not valid!
Run Code Online (Sandbox Code Playgroud)
我可以做一些聪明的C#,将System.Type转换回原来的C#类型吗?或者其他一些方法,创建一个可以(1)给我关于System.Type的信息的通用,以及(2)创建关联C#类型的对象?
顺便说一句,这是一个非常人为的例子来解释我试图解决的问题,不要太担心Generic是否有意义!
你唯一能做的就是使用反射。这是因为虽然intofGeneric<int>在编译时已知,但field.FieldType只有在运行时才知道。
反射示例:
Type type = typeof(Generic<>).MakeGenericType(field.FieldType);
// Object of type Generic<field.FieldType>
object gen = Activator.CreateInstance(type);
Run Code Online (Sandbox Code Playgroud)
但即使在这里,从一个Type( field.FieldType) 你得到另一个Type( type)
通常有三种使用方法:
Generic<type>完全反射:您仅通过反射来使用类型的对象。您通过创建它Activator.CreateInstance并从那里开始使用Type.GetMethod()和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);
Run Code Online (Sandbox Code Playgroud)
Generic<T>. 您仅通过该接口/基类使用您的对象。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);
Run Code Online (Sandbox Code Playgroud)
Generic<T>. 这是通过反射使用的唯一方法。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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2453 次 |
| 最近记录: |