2012-08-03 200 views
0

如果我有一个类接受来自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

您正在使用哪种C#版本? – Arcturus 2012-08-03 13:29:20

回答

4

这是因为generi具有不同类型的cs与彼此不兼容。为了解决这个问题,你可以声明泛型参数来Isomeclass使用

public interface Isomeclass<out TUser> 
    where TUser : class, IUser 
{ 

    string test(TUser user); 
    TUser returnUser(); 
} 

然而,这将打破test方法,因为它不再是类型安全进行协变的。为了解决这个问题,您可以将参数user类型更改为IUser,它将像以前一样工作。

这取决于您使用的C#版本。对于一些旧版本,泛型不能声明为协变,这意味着您必须将赋值目标更改为与分配给它的对象相同的类型。

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并进行一些铸造。

1

someclass<ElimCMS.DataModel.Users.User>不是分配兼容的。实际上,和Isomeclass<ElimCMS.DataModel.Users.User>不能被分配给对方。

由于您希望使用类型参数TUser指定的类型作为输入参数和输出参数,因此不能将类型参数声明为协变或逆变,因此唯一的解决方案是在接口中保留当前方法签名/班似乎是键入列表实例IUser

new someclass<ElimCMS.DataModel.Users.IUser>(); 

或键入您的列表变量User

Isomeclass<ElimCMS.DataModel.Users.User> servicetest