我在基础库项目中定义了以下接口:

public interface IWorkContext {
    T User<T>() where T : IUser;

    // Note this method is kind of a shortcut so i don't
    // have to keep passing in T
    IUser User();
}

public interface IUser {
    int Id { get; }
    string UserName { get; }
}


现在,我有另一个项目,该项目使用以下类(实现IUser)引用了上面的一个。

public class User : IUser {
   public virtual int Id { get; set; }
   public virtual string UserName { get; set; }
   // ... Code removed for brevity
}


现在,我还需要实现IWorkContext。这是我的第一次尝试:

public class DefaultWorkContext : IWorkContext {
    private readonly IUsersService _usersService;

    public DefaultWorkContext(IUsersService usersService) {
        _usersService = usersService;
    }

    public T User<T>() where T : IUser {
        return _usersService.GetUser<T>(1));
    }

    public User User() {
        return User<User>();
    }
}


但这给出了错误:


  类型“ T”不能用作通用类型中的类型参数“ T”
  或方法'... GetUser(int)'。没有装箱转换或类型
  参数从“ T”转换为“用户”。


我确定我做错了一些根本的事情。我很高兴可以对此模型提出任何建议。谢谢

编辑(根据要求,这里是GetUser方法):

public T GetUser<T>(int id) where T : User {
    return _session.Get<T>(id);
}


注意:_session是NHibernate会话。

最佳答案

这里的问题是您正在将泛型作为类型参数传递给GetUser()方法,这可能不满足您的GetUser()方法所接受的泛型类型的继承条件。

编译器确保作为参数传递的类型始终满足类型条件。
确实,您可以编写一个实现class NotUser而不是IUserUser
然后,可以使用User<T>()作为类型参数调用NotUser方法,这将导致使用不从GetUser()继承的类型参数调用User

您的GetUser()方法仅接受从User继承的类型。

您需要更改GetUser()原型以接受实现IUser的通用类型,或者更改User<T>原型以仅接受从User继承的通用类型。

可以这样:

public T GetUser<T>(int id) where T : IUser {
    return _session.Get<T>(id);
}


或这个:

public T User<T>() where T : User {
    return _usersService.GetUser<T>(1));
}


编辑:
您应该选择第一种方法还是第二种方法取决于您要执行的操作。

1)您希望您的IWorkContext使用IUser界面,并且您接受GetUser()方法返回IUser =>选择选项1

2)您希望GetUser()方法采用从User继承的类型,并且您接受IWorkContext接口可用于User而不是IUser =>选择选项2,并修改界面。

对我来说,选项1)更好,因为您不需要修改接口,也不会破坏通用性。但这取决于您要确切执行的操作。

关于c# - 实现基本接口(interface)问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12373517/

10-11 09:26