如果我有一个类接受从IUser派生的泛型类型,我该如何避免此错误消息
无法将
ElimCMS.Service.Users.someclass<ElimCMS.DataModel.Users.User>
类型隐式转换为ElimCMS.Service.Users.Isomeclass<ElimCMS.DataModel.Users.IUser>
。存在显式转换(您是否错过了演员?)
实施例
public interface Isomeclass<TUser>
where TUser : class, IUser
{
string test(TUser user);
TUser returnUser();
}
public class someclass<TUser> : Isomeclass<TUser>
where TUser : class, IUser, new()
{
public string test(TUser user)
{
string email = user.EMail;
user.EMail = "changed:" + email;
return email;
}
public TUser returnUser()
{
throw new NotImplementedException();
}
}
Isomeclass<ElimCMS.DataModel.Users.IUser> servicetest = new someclass<ElimCMS.DataModel.Users.User>();
答案 0 :(得分:5)
这是因为具有不同类型的泛型彼此不兼容。要解决此问题,您可以使用
将通用参数声明为Isomeclass
以协变
public interface Isomeclass<out TUser>
where TUser : class, IUser
{
string test(TUser user);
TUser returnUser();
}
但是,这会破坏test
方法,因为它不再是类型安全的。要解决此问题,您可以将参数user
类型更改为IUser
,它将像以前一样工作。
这取决于您使用的C#版本。对于某些旧版本,泛型不能声明为协变,这意味着您必须将赋值目标更改为与分配给它的对象相同的类型。
答案 1 :(得分:2)
Isomeclass<ElimCMS.DataModel.Users.IUser>
和someclass<ElimCMS.DataModel.Users.User>
不兼容分配。实际上,Isomeclass<ElimCMS.DataModel.Users.IUser>
和Isomeclass<ElimCMS.DataModel.Users.User>
无法相互分配。
由于您希望使用类型参数TUser
指定的类型作为输入和输出参数,因此您不能将类型参数声明为协变或逆变,因此保留当前方法签名的唯一解决方案在你的接口/类中似乎是要将列表实例键入IUser
:
new someclass<ElimCMS.DataModel.Users.IUser>();
或将列表变量键入User
:
Isomeclass<ElimCMS.DataModel.Users.User> servicetest
答案 2 :(得分:1)
更改声明
public interface Isomeclass<TUser> where TUser : class, IUser
{
string test(TUser user);
TUser returnUser();
}
到
public interface Isomeclass<out TUser> where TUser : class, IUser
{
string test(IUser user);
TUser returnUser();
}
并在test
中相应地重新定义someclass<TUser>
方法以匹配。
如果您使用的是C#4(Visual Studio 2010)或更高版本,则可以执行此操作。这将为您提供所需的一切。如果您使用的是先前版本,那么您必须恢复为object
并进行投射。