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));
}