簡體   English   中英

轉換為基數 class 會拋出 InvalidCastException

[英]Casting to base class throws InvalidCastException

我的一個程序集包含以下“提供者”類型:

繼承樹

我還有一個 XML 文件,它使用DeviceInfoProvider基 class 保存提供者信息。簡化版本如下所示:

<DeviceInfoProvider Type="SbRioI2CProvider" Assembly="assembly.dll" >
</DeviceInfoProvider>
<DeviceInfoProvider Type="GenericProvider" Assembly="assembly.dll" >
</DeviceInfoProvider>

在運行時,我將 map XML 字段添加到我的變量中:

assembly.dll  ⇒ assemblyPath
Type          ⇒ typeName

在閱讀 XML 之后,使用以下代碼實例化我的類型:

var assembly = Assembly.LoadFrom(assemblyPath);

var type = (from t in assembly.GetTypes()
            where t.IsPublic && t.Name == typeName
            select t).FirstOrDefault();

if (type != null)
{
    instance = type.GetConstructor(Type.EmptyTypes).Invoke(null);
}

正如預期的那樣,這會適當地生成我的對象。

當我嘗試將實例轉換為基礎 class object 時,問題就來了:

using (var provider = instance as DeviceInfoProvider)
{
    // provider is null!
}

instance的運行時類型是預期的派生 class,但我無法成功地將其轉換為其基類型。

我錯過了什么?

您的問題可能是您正在從 LoadFrom 上下文中的 assembly.dll 中的類型創建實例(GenericProvider、SbRioI2CProvider)。 然后您嘗試按名稱轉換為該程序集中的類型 (DeviceInfoProvider)。 這隱含地使用了 Load 上下文。 來自同一程序集但在不同上下文中加載的類型被運行時視為不同類型,因此轉換失敗並且您得到 null。本文提供了一些關於程序集綁定上下文的額外說明。

要使此轉換成功,您需要將在 LoadFrom 上下文中加載的Assembly獲取到 Load 上下文中。 有幾種方法可以做到這一點。 一種方法是將程序集放在 GAC 中。 另一種是從應用程序庫中刪除 assembly.dll,這樣它就不會被探測找到。 然后使用 AppDomain.AssemblyResolve 事件加載您通過 LoadFrom 獲得的Assembly

調用反射類型的構造函數不會創建它的實例。

要創建反射類型的實例,請調用Activator.CreateInstance

看起來這一行應該是:

if (type != null) {
    instance = Activator.CreateInstance(type)
}

這將導致instance的類型為object ,但現在您可以將其轉換為任何您想要的類型。

請參閱: http://msdn.microsoft.com/en-us/library/wccyzw83.aspx

暫無
暫無

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

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