Как ограничить доступ защищаемого члена только от первого уровня child C# - PullRequest
3 голосов
/ 08 апреля 2020

У меня есть 3 уровня классов.

  • TopClass
  • MiddleClass
  • BottomClass

А MiddleClass является производным от TopClass и BottomClass является производным от MiddleClass.

Я хочу иметь свойство в TopClass, которое может быть доступно только с TopClass и MiddleClass, а не с BottomClass.

Поскольку я использую protected модификатор доступа, защищенное свойство в TopClass доступно из BottomClass.

Вот мои уроки, чтобы лучше понять.

public class TopClass
 {
    private string ThisIsOnlyAccessibleForTopClass { get; set; } 
    protected string ThisIsOnlyAccessibleForTopClassAndMiddleClass { get; set; } // I want this to be accessible only by the MiddleClass 
    public string AccessibleFromEverywhere { get; set; } // this is good as it is public so accessible everywhere

    public virtual void SomeWeirdFunction()
    {
       ThisIsOnlyAccessibleForTopClass = "I can access this here as it is grand father's private member!"; 
    }
 }


 public class MiddleClass : TopClass
 {
     public override void SomeWeirdFunction()
     {
         base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "As this is a MiddleClass class, I am accessible here.. That is good!";
     }
 }


 public class BottomClass : MiddleClass
 {
     public override void SomeWeirdFunction()
     {
         base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "I don't want this to be accessible here!";
     }
 }

Я хочу, чтобы ThisIsOnlyAccessibleForTopClassAndMiddleClass был доступен только из MiddleClass и TopClass, а не из BottomClass.

Как я могу это сделать? И поскольку я не могу сделать это с существующими модификаторами доступа, такими как protected, public, internal, private et c .. это признак того, что я пытаюсь нарушить какое-то правило здесь?

1 Ответ

3 голосов
/ 08 апреля 2020

Если у вас есть спецификатор c MiddleClass, который должен иметь привилегированный доступ к члену TopClass, вы можете поместить MiddleClass в TopClass как вложенный тип. Вложенные типы имеют доступ ко всем членам их вмещающего типа.

public class TopClass
{
    private string ThisIsOnlyAccessibleForTopClass { get; set; } 
    private string ThisIsOnlyAccessibleForTopClassAndMiddleClass { get; set; } // I want this to be accessible only by the MiddleClass 
    public string AccessibleFromEverywhere { get; set; } // this is good as it is public so accessible everywhere

    public virtual void SomeWeirdFunction()
    {
        ThisIsOnlyAccessibleForTopClass = "I can access this here as it is grand father's private member!"; 
    }

    public class MiddleClass : TopClass
    {
        public override void SomeWeirdFunction()
        {
            base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "As this is a MiddleClass class, I am accessible here.. That is good!";
        }
    }

}

public class BottomClass : TopClass.MiddleClass
{
    public override void SomeWeirdFunction()
    {
        // compilation error:
        // base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "I don't want this to be accessible here!";
    }
}

Если у вас есть один или несколько классов MiddleClass в той же сборке, что и TopClass, и все классы BottomClass собираются быть в другой сборке, вы можете использовать private protected. Это означает «доступ только к тем классам, которые ОБА internal и protected», тогда как protected internal означает «доступ к классам, КОГДА-ЛИБО internal или protected».

// in Assembly A

public class TopClass
{
    private string ThisIsOnlyAccessibleForTopClass { get; set; } 
    private protected string ThisIsOnlyAccessibleForTopClassAndMiddleClass { get; set; } // I want this to be accessible only by the MiddleClass 
    public string AccessibleFromEverywhere { get; set; } // this is good as it is public so accessible everywhere

    public virtual void SomeWeirdFunction()
    {
        ThisIsOnlyAccessibleForTopClass = "I can access this here as it is grand father's private member!"; 
    }
}

public class MiddleClass : TopClass
{
    public override void SomeWeirdFunction()
    {
        base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "As this is a MiddleClass class, I am accessible here.. That is good!";
    }
}

// in Assembly B, which references Assembly A

public class BottomClass : MiddleClass
{
    public override void SomeWeirdFunction()
    {
        // compile error
        // base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "I don't want this to be accessible here!";
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...