[英]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.