Каков вариант использования модификатора (C# 7.2) "private protected"?



C# 7.2 вводит закрытый защищенный модификатор.



Я всегда защищал доступ к полям со свойствами, разрешая доступ через методы Get / Set, поскольку я обычно не хочу, чтобы внутреннее состояние моего объекта изменялось чем-либо, кроме моего собственного класса.



Я пытаюсь понять, почему языковая команда C# добавила эту функцию. После обширного поиска в google, а также чтения и просмотра "what's new" media (я смотрел пресс-релиз,подробности и видео от Mads Torgerson), Я все еще ничего не знаю.



Мне кажется, что это позволяет разработчику нарушить принцип замены Лискова, но это может быть потому, что я не понимаю, почему эта функция теперь существует.



Я понимаю, как его можно использовать, но не почему-пожалуйста, может ли кто-нибудь предоставить пример использования в реальном мире, а не надуманный в документах MSDN?

197   3  

3 ответов:

до C# 7.2 у нас было protected internal модификатор. Это действительно означает защищенный или внутренний, то есть-член A доступно для дочерних классов, а также для любого класса в текущей сборке, даже если этот класс не является дочерним классом A (таким образом, ограничение, подразумеваемое "защищенным", ослабляется).

private protected действительно означает, protected и Internal. То есть-член доступен только для дочерних классов, которые находятся в той же сборке, но не для дочерних классов, которые находятся вне сборки (таким образом, ограничение, подразумеваемое "защищенным", сужается - становится еще более ограничительным). Это полезно, если вы строите иерархию классов в своей сборке и не хотите, чтобы какие-либо дочерние классы из других сборок получали доступ к определенным частям этой иерархии.

мы можем взять пример Джон Скит предоставил в комментариях. Предположим, у вас есть класс

public class MyClass {

}

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

наследование только в пределах текущей сборки может быть достигнуто с помощью внутреннего конструктора

public class MyClass {
    internal MyClass() {
    }
}

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

public class MyClass {
    protected MyClass() {
    }
}

а чтобы получить и то и другое-нужно private protected конструктора:

public class MyClass {
    private protected MyClass() {
    }
}

предположим, что у вас есть внутренний класс с именем SomeHelper что вы хотите использовать в рамках реализации общего абстрактного базового класса:

public abstract class Test
{
    // Won't compile because SomeHelper is internal.
    protected SomeHelper CreateHelper()
    {
        return new SomeHelper();
    }

    public int Func(int x)
    {
        var helper = CreateHelper();
        return helper.DoSomething(x);
    }
}

internal class SomeHelper
{
    public virtual int DoSomething(int x)
    {
        return -x;
    }
}

это не будет компилироваться, потому что вы не можете иметь защищенный метод, возвращающий внутренний тип. Ваш единственный выход-не использовать SomeHelper таким образом, или сделать SomeHelper общественности.

(вы могли бы сделать SomeHelper защищенный внутренний класс Test, но это не сработает, если SomeHelper предназначен для используется другими классами, которые не являются производными от базового класса.)

С введением private protected особенность, вы можете объявить CreateHelper() вот так:

private protected SomeHelper CreateHelper()
{
    return new SomeHelper();
}

теперь он будет компилироваться, и вам не нужно выставлять свои внутренние органы.

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

защищенная внутренняя

  • защищенный в другой сборке: доступно только в дочерних классах.

  • внутренние в текущей сборке: доступно всем в текущей сборке собрание.

private protected

  • private в другой сборке: недоступно.
  • защищенный в текущей сборке: доступно только в дочерних классах.
    Ничего не найдено.

Добавить ответ:
Отменить.