簡體   English   中英

使用Activator.CreateInstance進行通用類型轉換

[英]Generic type casting using Activator.CreateInstance

我有一個界面

public interface ISomething<TValue>
    where TValue : IConvertible
{
    ...
}

然后,我還有一些具有泛型方法的非泛型類:

public class Provider
{
    public static void RegisterType<TValue>(ISomething<TValue> instance)
        where TValue : IConvertible
    {
        ...
    }
}

直到我要在我的特定程序集中自動注冊所有適用的類型之前,這似乎還不錯。

public void InitializeApp()
{
    foreach(Type t in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ISomething<>).IsAssignableFrom(T)))
    {
        // ERROR
        Provider.RegisterType(Activator.CreateInstance(t));
    }
}

此代碼導致錯誤,因為無法從用法中推斷出參數類型。 我要么

  1. 使用我的通用方法RegisterType提供顯式的通用類型(由於代碼的動態性質,我不認為可以做到這一點)或
  2. 將結果從Activator.CreateInstance為適當的類型,以便可以從用法中推斷出參數類型

但是我也不知道該怎么辦? 也許還有我不知道的第三種選擇。

泛型是編譯時的功能,這意味着必須在編譯時知道泛型類型。 因此,當您僅在運行時知道類型時,就不能使用RegisterType方法,因為編譯器無法推斷出通用參數。

您在這里有幾個選擇。 您可以使用反射來調用正確版本的RegisterType (如注釋中所建議),或者可以創建RegisterType的其他非泛型重載,該重載接受對象並從中找出執行時類型。

對於前者,它看起來像這樣:

public void InitializeApp()
{
    foreach(Type t in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ISomething<>).IsAssignableFrom(T)))
    {
        var methodInfo = typeof( Provider ).GetMethod( "RegisterType", BindingFlags.Static );
        var registerTypeMethod = methodInfo.MakeGenericMethod( t );
        registerTypeMethod.Invoke( null, new[] { Activator.CreateInstance(t) } );
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM