C # интерфейсы с тем же именем метода - PullRequest
6 голосов
/ 23 сентября 2011

Я не знаю, если то, что я хотел бы сделать, просто невозможно, или я не думаю об этом правильно.

Я пытаюсь создать класс интерфейса репозитория, который принимаетуниверсальный тип и использует его в качестве основы для возврата большинства своих методов, то есть:

public interface IRepository<T> {
    void Add(T source);
    T Find(int id);
}

. Затем он наследуется реальным классом хранилища, например:

public class TestClientRepository : IRepository<ClientEmailAddress>, IRepository<ClientAccount> {

}

Идея состоит в том, что, например, в ClientRepository я хочу выполнять операции с несколькими различными типами объектов (ClientAccount, ClientEmailAddress и т. Д.);но в основном все необходимые типы операций одинаковы.

Когда я пытаюсь использовать TestClientRepository (после явной реализации интерфейсов), я не вижу несколько методов Find и Add.

Кто-нибудь может помочь?Спасибо.

Ответы [ 4 ]

5 голосов
/ 23 сентября 2011

Конечно - все, что вам нужно сделать, это использовать как соответствующий интерфейс:

TestClientRepository repo = new TestClientRepository();

IRepository<ClientEmailAddress> addrRepo = repo;
ClientEmailAddress address = addrRepo.Find(10);

IRepository<ClientAccount> accountRepo = repo;
ClientAccount accoutn = accountRepo.Find(5);

Практически явно реализованные методы интерфейса могут вызываться только для выражения типа интерфейса, а не для конкретного типа, реализующего интерфейс.

2 голосов
/ 23 сентября 2011

Поскольку общие параметры в унаследованных интерфейсах различаются, не действительно требуется явная реализация интерфейса для Add.

К сожалению, универсальный параметр не влияет на сигнатуру 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.
2 голосов
/ 23 сентября 2011

Вы сказали:

(после явной реализации интерфейсов)

Когда вы реализуете интерфейс явно, единственный способ «увидеть» эти методы -объект приведен к явно реализованному типу.Поэтому, если вы хотите использовать его как IRepository<ClientEmailAddress>, вам придется разыграть как таковой.Использование его в качестве TestClientRepository не позволит вам увидеть какие-либо явно реализованные методы.

0 голосов
/ 23 сентября 2011

Когда я явно реализовал интерфейс для одного из интерфейсов, я не смог использовать ключевое слово 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" });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...