我不知道我想做什么是不可能的:或者我没有以正确的方式思考它。
我正在尝试构建一个接受泛型类型的存储库接口类,并将其作为大多数方法返回的基础,即:
public interface IRepository<T> {
void Add(T source);
T Find(int id);
}
这将由实际的存储库类继承,如下所示:
public class TestClientRepository : IRepository<ClientEmailAddress>, IRepository<ClientAccount> {
}
这个想法是在ClientRepository中,例如,我想对几种不同的对象类型(ClientAccount,ClientEmailAddress等)执行操作;但总的来说,所需的操作类型都是一样的。
当我尝试使用TestClientRepository时(在显式实现Interfaces之后),我看不到多个Find和Add方法。
有人可以帮忙吗? 感谢。
答案 0 :(得分:5)
当然 - 您所要做的就是将用作相应的界面:
TestClientRepository repo = new TestClientRepository();
IRepository<ClientEmailAddress> addrRepo = repo;
ClientEmailAddress address = addrRepo.Find(10);
IRepository<ClientAccount> accountRepo = repo;
ClientAccount accoutn = accountRepo.Find(5);
基本上显式实现的接口方法只能在接口类型的表达式上调用 ,而不能在实现接口的具体类型上调用。
答案 1 :(得分:2)
你说:
(明确实现接口后)
当您显式实现接口时,“查看”这些方法的唯一方法是将对象强制转换为显式实现的类型。因此,如果您想将其用作IRepository<ClientEmailAddress>
,则必须投射它。将其用作TestClientRepository
将不会让您看到任何明确实现的方法。
答案 2 :(得分:2)
由于继承接口中的泛型参数不同,因此不实际上需要Add
的{{3}}。
不幸的是,通用参数不会影响Find
的签名,但可以仍然选择两个Find
中的一个作为“默认”。例如:
interface IRepository<T> {
void Add(T source);
T Find(int id);
}
class ClientEmailAddress {
}
class ClientAccount {
}
class TestClientRepository : IRepository<ClientEmailAddress>, IRepository<ClientAccount> {
public void Add(ClientEmailAddress source) {
throw new NotImplementedException();
}
public void Add(ClientAccount source) {
throw new NotImplementedException();
}
public ClientAccount Find(int id) {
throw new NotImplementedException();
}
ClientEmailAddress IRepository<ClientEmailAddress>.Find(int id) {
throw new NotImplementedException();
}
}
// ...
var x = new TestClientRepository();
x.Find(0); // Calls IRepository<ClientAccount>.Find.
((IRepository<ClientAccount>)x).Find(0); // Same as above.
((IRepository<ClientEmailAddress>)x).Find(0); // Calls IRepository<ClientEmailAddress>.Find.
答案 3 :(得分:0)
当我为其中一个接口显式实现接口时,我无法使用var关键字
var tcr = new TestClientRepository();
tcr. -- nothing there.
当我指定类型时,它按预期工作。
IRepository<ClientAccount> ca = new TestClientRepository();
ca.Add(new ClientAccount { AccountName = "test2" });
IRepository<ClientEmailAddress> cea = new TestClientRepository();
cea.Add(new ClientEmailAddress { Email = "test2@test.com" });