Ограничение доступности методов доступа (Руководство по программированию на C#)

Части свойства get и set или индексатора называются методами доступа. По умолчанию эти методы доступа обладают той же видимостью или уровнем доступа, присущим свойству или индексатору, которому они принадлежат. Дополнительные сведения см. в разделе уровни доступности. Однако иногда имеет смысл ограничить доступ к одному из этих методов доступа. Как правило, для этого ограничивается доступность метода доступа set и сохраняется открытая доступность метода доступа get. Примеры.

private string name = "Hello";

public string Name
{
    get
    {
        return name;
    }
    protected set
    {
        name = value;
    }
}

В этом примере свойство с именем Name определяет метод доступа get и set. Метод доступа get получает уровень доступности самого свойства – в этом случае это public, а метод доступа set ограничивается явным образом путем применения модификатора доступа protected к самому методу доступа.

Ограничения модификаторов доступа в методах доступа

Использование модификаторов доступа для свойств или индексаторов подчиняется следующим условиям:

  • Модификаторы доступа нельзя использовать в интерфейсе или в явной реализации члена интерфейса.

  • Модификаторы доступа можно использовать только в том случае, если как свойство, так и индексатор имеют модификаторы доступа set и get. В этом случае, модификатор разрешен в одном из двух методов доступа.

  • Если свойство или индексатор имеет модификатор override, модификатор доступа должен соответствовать методу доступа переопределенного метода доступа, если он существует.

  • Уровень доступности в методе доступа должен быть более ограничивающим, чем уровень доступности в самом свойстве или индексаторе.

Модификаторы доступа в переопределяющих методах доступа

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

public class Parent
{
    public virtual int TestProperty
    {
        // Notice the accessor accessibility level. 
        protected set { }

        // No access modifier is used here. 
        get { return 0; }
    }
}
public class Kid : Parent
{
    public override int TestProperty
    {
        // Use the same accessibility level as in the overridden accessor. 
        protected set { }

        // Cannot use access modifier here. 
        get { return 0; }
    }
}

Реализация интерфейсов

При использовании метода доступа для реализации интерфейса, метод доступа не может иметь модификатор доступа. Однако если интерфейс реализуется при помощи одного метода доступа, такого как get, другой метод доступа может иметь модификатор доступа, как в следующем примере:

public interface ISomeInterface
{
    int TestProperty
    {
        // No access modifier allowed here 
        // because this is an interface. 
        get;
    }
}

public class TestClass : ISomeInterface
{
    public int TestProperty
    {
        // Cannot use access modifier here because 
        // this is an interface implementation. 
        get { return 10; }

        // Interface property does not have set accessor, 
        // so access modifier is allowed. 
        protected set { }
    }
}

Домен доступности к методу доступа

При использовании модификатора доступа в методе доступа, этот модификатор определяет домен доступности метода доступа.

Если модификатор доступа в методе доступа не используется, домен доступности метода доступа определяется уровнем доступности свойства или индексатора.

Пример

В следующем примере содержатся три класса: BaseClass, DerivedClass и MainClass. В BaseClass, Name и Id для обоих классов имеется два свойства. Пример демонстрирует, как свойство Id в DerivedClass можно скрыть при помощи свойства Id в BaseClass, если используется ограничивающий модификатор доступа, такой как protected или private. Таким образом, при присвоении значений этому свойству, вместо этого вызывается свойство BaseClass. Замена модификатора доступа модификатором public сделает свойство доступным.

Пример также демонстрирует, что ограничивающий модификатор доступа, такой как private или protected, в методе доступа set свойства Name в DerivedClass запрещает доступ к методу доступа и создает ошибку при его присвоении.

public class BaseClass
{
    private string name = "Name-BaseClass";
    private string id = "ID-BaseClass";

    public string Name
    {
        get { return name; }
        set { }
    }

    public string Id
    {
        get { return id; }
        set { }
    }
}

public class DerivedClass : BaseClass
{
    private string name = "Name-DerivedClass";
    private string id = "ID-DerivedClass";

    new public string Name
    {
        get
        {
            return name;
        }

        // Using "protected" would make the set accessor not accessible. 
        set
        {
            name = value;
        }
    }

    // Using private on the following property hides it in the Main Class. 
    // Any assignment to the property will use Id in BaseClass. 
    new private string Id
    {
        get
        {
            return id;
        }
        set
        {
            id = value;
        }
    }
}

class MainClass
{
    static void Main()
    {
        BaseClass b1 = new BaseClass();
        DerivedClass d1 = new DerivedClass();

        b1.Name = "Mary";
        d1.Name = "John";

        b1.Id = "Mary123";
        d1.Id = "John123";  // The BaseClass.Id property is called.

        System.Console.WriteLine("Base: {0}, {1}", b1.Name, b1.Id);
        System.Console.WriteLine("Derived: {0}, {1}", d1.Name, d1.Id);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}
/* Output:
    Base: Name-BaseClass, ID-BaseClass
    Derived: John, ID-BaseClass
*/

Комментарии

Обратите внимание, что при замене объявления new private string Id new public string Id, результат будет следующим:

Name and ID in the base class: Name-BaseClass, ID-BaseClass

Name and ID in the derived class: John, John123

См. также

Ссылки

Свойства (Руководство по программированию в C#)

Индексаторы (Руководство по программированию в C#)

Модификаторы доступа (Руководство по программированию в C#)

Основные понятия

Руководство по программированию на C#