我在基础库项目中定义了以下接口:
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
而不是IUser
的User
。
然后,可以使用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
=>选择选项12)您希望
GetUser()
方法采用从User
继承的类型,并且您接受IWorkContext
接口可用于User
而不是IUser
=>选择选项2,并修改界面。对我来说,选项1)更好,因为您不需要修改接口,也不会破坏通用性。但这取决于您要确切执行的操作。
关于c# - 实现基本接口(interface)问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12373517/