我可以创建一个通用类,将 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;
但是现在让我们说说我拥有的是一个 System.Type。我不能用它来实例化我的泛型类:
FieldInfo field = foo();
Generic<field.FieldType> g; // Not valid!
我可以做一些聪明的 C# 事情,将 System.Type 转换回原始的 C# 类型吗?或者以其他方式创建一个泛型,它可以 (1) 提供有关 System.Type 的信息,以及 (2) 创建关联 C# 类型的对象?
顺便说一句,这是一个非常人为的例子来解释我要解决的问题,不要太担心泛型是否有意义!
最佳答案
你唯一能做的就是使用反射。这是因为虽然 int
的 Generic<int>
在编译时已知,field.FieldType
仅在运行时已知。
反射示例:
Type type = typeof(Generic<>).MakeGenericType(field.FieldType);
// Object of type Generic<field.FieldType>
object gen = Activator.CreateInstance(type);
但即使在这里,来自 Type
( field.FieldType
) 你得到另一个 Type
( type
)
通常有三种使用方法:
- 全反射:你使用类型为
Generic<type>
的对象只有通过反射(reflection)。您通过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);
- 接口(interface)/基类:你有一个非通用的基类或接口(interface),它在所有
Generic<T>
之间是通用的。 .您只能通过该接口(interface)/基类使用您的对象。
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>
的所有处理.这是唯一通过反射使用的方法。
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);
关于c# - 可以从 C# 类型转换为 System.Type,但反之则不行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29978600/