簡體   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