我有一组类都参与了一个继承链,列在本文的底部,最后两种类型和后面的方法是抽象库的一部分,第一类是这样的用法。
我遇到的问题是使用UserService
实例化Activator.CreateInstance
类型 - 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]'.
答案 0 :(得分:3)
看起来你正在打电话:
LoadServiceType<DataContext, ConnectionProvider, IDataEntity>(typeof(UserService));
那是行不通的,因为它试图转向
IDataService<DataContext, ConnectionProvider, IDataEntity>
当UserService
实际实现时
IDataService<DataContext, ConnectionProvider, User>
您会发现,如果您更改测试代码以尝试使用IDataEntity
作为类型参数而不是User
进行投射,则会以相同的方式失败。
这与泛型差异有关。这是一个很大的话题 - Eric Lippert有一个whole series of blog posts on it,去年我在NDC上发表了一个演讲...我不知道有关谈话的流媒体网站是否仍然可用,但你可以抓住一个所有谈话的洪流here。
举一个非常简单的例子,你不能以完全相同的方式将IList<string>
强制转换为IList<object>
- 否则这会编译,但必须在执行时失败:
IList<string> strings = new List<string>();
IList<object> objects = strings;
objects.Add(new object());
string firstString = strings[0]; // Eek!