c# - 可以从 C# 类型转换为 System.Type,但反之则不行

标签 c# generics

我可以创建一个通用类,将 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# 类型的对象?

顺便说一句,这是一个非常人为的例子来解释我要解决的问题,不要太担心泛型是否有意义!

最佳答案

你唯一能做的就是使用反射。这是因为虽然 intGeneric<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/

相关文章:

c# - 图像路径在 CDN 中有效,但在 .css 中无效

C#:使用滚动条缩放图片框图像的简单而实用的方法

java - Gradle - Java 项目 - 通用 For 循环

ios - Swift 中泛型关联类型的比较类型

c# - 具有泛型参数的扩展方法到泛型类

c# - 如果已经打开,请关闭 Telerik Radgrid Editform

c# - 将 4 字节十六进制值转换为十进制值

Java泛型类型推导错误

scala - 对两种类型之间的二元关系建模

c# - 并行 Foreach 和操作