Подтвердить что ты не робот

Как реализовать элементы внутренних интерфейсов

Я реорганизую базу кода проекта, в которой я сейчас работаю, чтобы классы/интерфейсы, которые не полезны вне пределов сборки, должны быть объявлены как внутренние (а не публичные). Но у меня возникла проблема со следующим кодом:

internal interface IFirstInterface
{
    ...
}

internal interface ISecondInterface
{
    IFirstInterface First{ get; }
    ...
}

public class Implementer : ISecondInterface
{
    public IFirstInterface First {get; private set;}
    ...
}

Мои вопросы:

  • Почему члены внутренних интерфейсов должны публично реализовываться? Если вы реализуете интерфейс во внутреннем классе, не должны ли реализованные члены быть внутренними? Это не большая проблема, так как члены интерфейса не будут общедоступными в любом случае, учитывая, что класс является внутренним. Это просто кажется интуитивным.

  • Основная проблема связана со сценарием выше, поскольку я не могу иметь публичный getter для IFirstInterface, поскольку он предположительно является внутренним интерфейсом, то есть я получаю следующую ошибку от компилятора:

Непоследовательная доступность: свойство тип "IFirstInterface" меньше доступный, чем собственность 'Implementer.First'

Есть ли способ обойти это?

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

4b9b3361

Ответ 1

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

В этом отношении используется явная реализация интерфейса:

public class Implementer : ISecondInferface
{
    private IFirstInterface first;
    IFirstInterface ISecondInterface.First { get { return first; } }
}

У вас не может быть установщика там, потому что вы явно реализуете интерфейс, который не определяет установщик. Вы можете сделать это в качестве альтернативы:

public class Implementer : ISecondInterface
{
    internal IFirstInterface First { get; private set; }
    IFirstInterface ISecondInterface.First { get { return First; } }
}

Несчастливо, что внутренние интерфейсы имеют публичные члены - это усложняет такие вещи. Было бы странно, если бы в публичном интерфейсе был внутренний член (что бы он был внутренним - разработчик или декларант?), Но для внутренних интерфейсов это имеет гораздо больший смысл.

Ответ 2

Почему члены внутренних интерфейсов должны публично реализовываться?

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

Что касается раскрытия getter, я бы предложил сделать явную реализацию интерфейса и создать свойство internal, чтобы вывести значение:

internal IFirstInterface First { get; private set; }

IFirstInterface ISecondInterface.First
{
    get { return this.First; }
}

Ответ 3

Я знаю, что этому сообщению несколько лет, но я думаю, что стоит отметить, что вы можете реализовать внутренний интерфейс в открытом классе, см. следующие ссылки:

http://forums.create.msdn.com/forums/p/29808/167820.aspx

http://msdn.microsoft.com/en-us/library/aa664591%28VS.71%29.aspx

Пример из первой ссылки:


internal interface ISecretInterface
{
    string Property1 { get; }
}

public class PublicClass : ISecretInterface
{
    // class property
    public string Property1
    {
        get { return "Foo"; }
    }

    // interface property
    string ISecretInterface.Property1
    {
        get { return "Secret"; }
    }
}