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

StackOverflow https://stackoverflow.com/questions/1221392

  •  10-07-2019
  •  | 
  •  

Вопрос

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

internal interface IFirstInterface
{
    ...
}

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

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

Мои вопросы:

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

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

  •   

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

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

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

    Это было полезно?

    Решение

    Просто обратите внимание - код, который вы фактически предоставили, выполняет компиляцию, потому что 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; } }
    }
    

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

    Другие советы

      

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

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

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

    internal IFirstInterface First { get; private set; }
    
    IFirstInterface ISecondInterface.First
    {
        get { return this.First; }
    }
    

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

       http://forums.create.msdn.com/forums/p/29808/ 167820.aspx
       http://msdn.microsoft.com/en-us/ библиотека / 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"; }
        }
    }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top