Устранение неоднозначности в интерфейсе, который расширяет два других интерфейса, у которых есть метод с тем же именем - PullRequest
3 голосов
/ 15 февраля 2012

если у меня есть интерфейсы:

public interface ANewThing { IKey Key { get; } }

public interface AnOldThing { object Key{ get; } }

public interface ACompositeThing : ANewThing , AnOldThing  { }

, и я пишу это:

ACompositeThing compositeThing = GetCompositeThing();  
Trace.WriteLine(compositeThing.Key);

он не компилируется, жалуясь, что вызов Key неоднозначен (это нене имеет значения, если тип, возвращаемый свойством Key, совпадает).Я знаю, что в классе, реализующем ACompositeThing, я могу явно реализовать интерфейсы ANewThing и AnOldThing, но это не помогает мне, когда у меня есть методы, которые не знают о конкретных реализациях и знают только, что онибудет дан ACompositeThing.

Итак, мой вопрос:

Могу ли я что-нибудь сделать в интерфейсе ACompositeThing, чтобы сказать, как следует разрешить неоднозначность свойства Key?

Как, скажем, «при доступе к свойству Key через этот интерфейс всегда возвращать свойство Key из реализации ANewThing»?

Или я должен признать, что я не могу этого сделать и должен всегда приводить мой ACompositeThing к одному из других интерфейсов, прежде чем я сделаю доступ?

Ответы [ 4 ]

3 голосов
/ 15 февраля 2012

Это неприятно, но вы можете объявить другого члена в ACompositeThing:

public interface ACompositeThing : ANewThing , AnOldThing {
    new IKey Key { get; }
}

Теперь это будет иметь предпочтение с точки зрения вызывающего абонента .Тем не менее, это означает, что в настоящее время существует потенциально три различных реализации - и любая реализация ACompositeThing, использующая явную реализацию интерфейса для ANewThing.Key, будет либо должна измениться, чтобы выставить член публично,или добавьте нового члена для реализации ACompositeThing.Key.

Конечно, если вы возможно можете, вам следует избегать этого - или использовать его только при переходе от старого интерфейса к новому интерфейсув течение очень ограниченного времени.

0 голосов
/ 15 февраля 2012

Это классическая проблема, называемая «проблема с бриллиантами» или «наследование бриллиантов». В большинстве случаев это происходит из-за плохого дизайна ООП или плохих соглашений об именах. Я думаю, что это тоже ваша проблема.

Попробуйте немного погуглить "Алмазная проблема", есть различные решения.

0 голосов
/ 15 февраля 2012

Могу ли я что-нибудь сделать в интерфейсе ACompositeThing, чтобы сказать, как следует разрешить неоднозначность свойства Key?

Как, скажем, «при доступе к свойству Key через этот интерфейс всегда возвращать свойство Key из реализации ANewThing»?

Попробуйте этот код:

ANewThing newThing = GetCompositeThing();  
Trace.WriteLine(newThing.Key);

или

ACompositeThing compositeThing = GetCompositeThing();  
Trace.WriteLine(((ANewThing)compositeThing).Key);
0 голосов
/ 15 февраля 2012

Больше обходного пути, чем ответа: сделайте ACompositeThing базовым классом (вместо интерфейса), который явно реализует свойство Key.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...