C# 实现一个基本接口解决了许多问题

C# 实现一个基本接口解决了许多问题,c#,generics,interface,C#,Generics,Interface,我在基本库项目中定义了以下接口: 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; } s

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

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; }
}
现在我还需要实现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>();
    }
}
公共类DefaultWorkContext:IWorkContext{
专用只读IUsersService(用户服务);;
公共DefaultWorkContext(IUsersService usersService){
_usersService=usersService;
}
public T User(),其中T:IUser{
返回_usersService.GetUser(1));
}
公共用户(){
返回用户();
}
}
但是,这会产生错误:

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

我肯定我做错了一些基本的事情。如果您对这种型号有任何改进意见,我将不胜感激。谢谢

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

public T GetUser(int-id)其中T:User{
return _session.Get(id);
}

注意:\ U会话是一个NHibernate会话。

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

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

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

您需要更改
GetUser()
prototype以接受实现
IUser
的泛型类型,或者更改
User
prototype以仅接受从
User
继承的泛型类型

或者:

public T GetUser<T>(int id) where T : IUser {
    return _session.Get<T>(id);
}
public T GetUser(int-id)其中T:IUser{
return _session.Get(id);
}
或者这个:

public T User<T>() where T : User {
    return _usersService.GetUser<T>(1));
}
public T User(),其中T:User{
返回_usersService.GetUser(1));
}
编辑: 选择第一种方法还是第二种方法取决于您想做什么

1) 您希望您的
IWorkContext
IUser
接口一起工作,并且您接受
GetUser()
方法返回一个
IUser
=>选择选项1

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


对我来说,选项1)更好,因为您不需要修改接口,也不会破坏通用性。但是这取决于你想做什么。

我们可以得到你的UserService和GetUser方法的代码吗?还有,GetUser接受哪种泛型类型?我怀疑错误来自这里。我们需要查看IUserService…我已经用GetUser方法更新了问题。什么是
IUserService
?我也这么想,但由于用户实现了IUser,我认为它可以接受。请看我的示例。可能有一个类实现了IUser,但不从用户继承。编译器始终强制执行最强的条件,以避免类型不一致(我的意思是,如果需要用户类型,GetUser可以使用特定于用户而不是IUser的方法或字段)'DefaultWorkContext'不实现接口成员'IWorkContext.User()'DefaultWorkContext.User()无法实现“IWorkContext.User()”,因为它没有匹配的返回类型“IUser”。这是因为在选项2中修改where子句会导致DefaultWorkContext类中的User()方法未实现IWorkContext接口中描述的用户方法。您应该选择什么选项,以及您应该做什么完全取决于您希望对这些类/接口做什么。我会更新我的答案。谢谢。经过一段时间的重构,我想出了一些适合这个场景的方法。我遇到了另一个小问题,但这是无关的,所以我将在另一个问题中发布。再次感谢。
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));
}