簡體   English   中英

InvalidCastException:帶有常規繼承類型的Activator.CreateInstance

[英]InvalidCastException: Activator.CreateInstance w/ Generic Inheriting Type

我有一組全都屬於繼承鏈的類,在本文的底部列出,最后兩種類型以及它們后面的方法是抽象庫的一部分,而第一類是此類的用法。

我遇到的問題是使用Activator.CreateInstance實例化UserService類型時InvalidCastException我死了; 不過,這確實可以使人滿意,因此我可能只是忽略了最近(或愚蠢)更改過的內容。

如在運行時創建此實例的方法中所述,這是導致錯誤的代碼:

return (IDataService<DataContextType, DataConnectionProviderType, DataEntityType>)Activator.CreateInstance(service); 

但是,以下代碼成功:

var a = new UserService();
var b = (UserService<DataContext, ConnectionProvider, User, UserRole>)a;
var c = (DataService<DataContext, ConnectionProvider, User>)b;
var d = (IDataService<DataContext, ConnectionProvider, User>)c;

var e = (IDataService<DataContext, ConnectionProvider, User>)a;

誰能看到我看不到的東西?

不能完全確定這里發生了什么,但是有一個預感,可能與IDataEntity的類型有關。 用於檢查的代碼,詢問您是否還需要:

public class UserService
    : UserService<DataContext, ConnectionProvider, User, UserRole>
{
}

public class UserService<DataContextType, DataConnectionProviderType, UserType, UserRoleType>
    : DataService<DataContextType, DataConnectionProviderType, UserType>
    where DataContextType : DataContext<DataConnectionProviderType>, new()
    where DataConnectionProviderType : DataConnectionProviderBase, new()
    where UserType : class, IUser<UserRoleType>, IDataEntity
    where UserRoleType : class, IUserRole, IDataEntity
{
}

public abstract class DataService<DataContextType, DataConnectionProviderType, DataEntityType> 
    : IDataService<DataContextType, DataConnectionProviderType, DataEntityType>
        where DataContextType : DataContext<DataConnectionProviderType>, new()
        where DataConnectionProviderType : DataConnectionProviderBase, new()
        where DataEntityType : class, IDataEntity
{
}

public interface IDataService<DataContextType, DataConnectionProviderType, DataEntityType> : IDisposable
    where DataContextType : DataContext<DataConnectionProviderType>, new()
    where DataConnectionProviderType : DataConnectionProviderBase, new()
    where DataEntityType : class, IDataEntity
{
}

public static IDataService<DataContextType, DataConnectionProviderType, DataEntityType>
    LoadServiceType<DataContextType, DataConnectionProviderType, DataEntityType>(Type service)
    where DataContextType : DataContext<DataConnectionProviderType>, new()
    where DataConnectionProviderType : DataConnectionProviderBase, new()
    where DataEntityType : class, IDataEntity
{
    ...

    return (IDataService<DataContextType, DataConnectionProviderType, DataEntityType>)Activator.CreateInstance(service);             
}

異常詳細信息:

System.InvalidCastException: Unable to cast object of type '...UserService' to type '...IDataService'3[...DataContext,...Domain.Data.ConnectionProvider,...IDataEntity]'.

看來您實際上在打電話:

LoadServiceType<DataContext, ConnectionProvider, IDataEntity>(typeof(UserService));

那是行不通的,因為它正在嘗試轉換為

IDataService<DataContext, ConnectionProvider, IDataEntity>

UserService實際實現時

IDataService<DataContext, ConnectionProvider, User>

您會發現,如果您更改測試代碼以嘗試使用IDataEntity作為類型參數(而不是User進行類型轉換,則它將以相同的方式失敗。

這全都與泛型方差有關 這是一個很大的話題-埃里克·利珀特(Eric Lippert)上有很多博客文章 ,去年我在NDC上發表了演講...我不知道是否可以繼續進行該演講的流媒體網站,但是您可以抓住這里所有談話的洪流。

舉一個非常簡單的例子,您不能以完全相同的方式將IList<string> IList<object>IList<object> -否則會編譯,但必須在執行時失敗:

IList<string> strings = new List<string>();
IList<object> objects = strings;
objects.Add(new object());
string firstString = strings[0]; // Eek!

暫無
暫無

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

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