繁体   English   中英

c# - 可以从C#类型转换为System.Type但反之亦然

[英]c# - can convert from C# type to System.Type but not vice-versa

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

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

你唯一能做的就是使用反射。 这是因为,而intGeneric<int>是在编译时已知的, field.FieldType仅在运行时是已知的。

反思例子:

Type type = typeof(Generic<>).MakeGenericType(field.FieldType);

// Object of type Generic<field.FieldType>
object gen = Activator.CreateInstance(type);

但即便在这里,从Typefield.FieldType )中获取另一个Typetype

通常有三种使用方法:

  • 完全反射:您只能通过反射使用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);
  • 接口/基类:你有一个非通用的基类或接口,它在所有Generic<T>之间是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);
  • 一种通用方法,您可以对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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM