1

如果我有一个接受从 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>();
4

3 回答 3

5

发生这种情况是因为具有不同类型的泛型彼此不兼容。为了解决这个问题,您可以使用声明您的泛型参数Isomeclass是协变的

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

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

但是,这将破坏该test方法,因为它不再是类型安全的。要解决这个问题,您可以将参数user类型更改为IUser,它会像以前一样工作。

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

于 2012-08-03T13:34:45.853 回答
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
于 2012-08-03T13:34:00.083 回答
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并进行一些转换。

于 2012-08-03T13:32:49.287 回答