アクセサーのアクセシビリティの制限 (C# プログラミング ガイド)Restricting Accessor Accessibility (C# Programming Guide)

プロパティまたはインデクサーの get および set 部分は、アクセサーと呼ばれます。The get and set portions of a property or indexer are called accessors. 既定では、これらのアクセサーは、それらが属するプロパティまたはインデクサーと同じ可視性またはアクセス レベルを持っています。By default these accessors have the same visibility, or access level: that of the property or indexer to which they belong. 詳細については、「アクセシビリティ レベル」を参照してください。For more information, see accessibility levels. ただし、これらのアクセサーのいずれかにアクセスを制限すると便利な場合があります。However, it is sometimes useful to restrict access to one of these accessors. 通常、これには、set アクセサーのアクセシビリティを制限しながら、get アクセサーのパブリック アクセスを維持する操作が含まれます。Typically, this involves restricting the accessibility of the set accessor, while keeping the get accessor publicly accessible. 例:For example:

private string name = "Hello";

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

この例では、Name というプロパティが get および set アクセサーを定義します。In this example, a property called Name defines a get and set accessor. get アクセサーは、プロパティ自体のアクセシビリティ レベル (この場合は public) を受け取り、同時に set アクセサーは、protected アクセサー修飾子をアクセサー自体に適用することによって明示的に制限されます。The get accessor receives the accessibility level of the property itself, public in this case, while the set accessor is explicitly restricted by applying the protected access modifier to the accessor itself.

アクセサーのアクセス修飾子の制限Restrictions on Access Modifiers on Accessors

プロパティまたはインデクサーでのアクセサー修飾子の使用は、以下の条件の対象になります。Using the accessor modifiers on properties or indexers is subject to these conditions:

  • インターフェイスまたは明示的な interface メンバーの実装でアクセサー修飾子を使用することはできません。You cannot use accessor modifiers on an interface or an explicit interface member implementation.

  • アクセサー修飾子は、プロパティまたはインデクサーに setget アクセサーの両方がある場合にのみ使用できます。You can use accessor modifiers only if the property or indexer has both set and get accessors. この場合、修飾子は、2 つのアクセサーのいずれかでのみ許可されます。In this case, the modifier is permitted on one only of the two accessors.

  • プロパティまたはインデクサーに override 修飾子がある場合は、アクセサー修飾子はオーバーライドされるアクセサーのアクセサー (存在する場合) と一致する必要があります。If the property or indexer has an override modifier, the accessor modifier must match the accessor of the overridden accessor, if any.

  • アクセサーのアクセシビリティ レベルは、プロパティまたはインデクサー自体のアクセシビリティ レベルよりも制限されていなければなりませんThe accessibility level on the accessor must be more restrictive than the accessibility level on the property or indexer itself.

オーバーライドするアクセサーのアクセス修飾子Access Modifiers on Overriding Accessors

プロパティまたはインデクサーをオーバーライドする場合は、オーバーライドされたアクセサーがオーバーライドするコードにアクセスできなければなりません。When you override a property or indexer, the overridden accessors must be accessible to the overriding code. プロパティ/インデクサーの両方のアクセシビリティ レベル、およびアクセサーのアクセシビリティレベルが、対応するオーバーライドされるプロパティ/インデクサーおよびアクセサーと一致している必要があります。Also, the accessibility level of both the property/indexer, and that of the accessors must match the corresponding overridden property/indexer and the accessors. 例:For example:

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; }
    }
}

インターフェイスの実装Implementing Interfaces

アクセサーを使用してインターフェイスを実装する場合、アクセサーがアクセス修飾子を持つことはできません。When you use an accessor to implement an interface, the accessor may not have an access modifier. ただし、get などの 1 つのアクセサーを使用してインターフェイスを実装する場合、他のアクセサーは、次の例のように、アクセス修飾子を持つことができます。However, if you implement the interface using one accessor, such as get, the other accessor can have an access modifier, as in the following example:

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 { }
    }
}

アクセサー アクセシビリティ ドメインAccessor Accessibility Domain

アクセサーでアクセス修飾子を使用する場合、アクセサーのアクセシビリティ ドメインはこの修飾子によって決まります。If you use an access modifier on the accessor, the accessibility domain of the accessor is determined by this modifier.

アクセサーでアクセス修飾子を使用しなかった場合、アクセサーのアクセシビリティ ドメインは、プロパティまたはインデクサーのアクセシビリティ レベルによって決まります。If you did not use an access modifier on the accessor, the accessibility domain of the accessor is determined by the accessibility level of the property or indexer.

Example

次の例は、BaseClassDerivedClass、および MainClass という 3 つのクラスを含んでいます。The following example contains three classes, BaseClass, DerivedClass, and MainClass. すべてのクラスの BaseClassNameId に 2 つのプロパティがあります。There are two properties on the BaseClass, Name and Id on both classes. この例は、protectedprivate などの制限アクセス修飾子を使用するときに、BaseClass のプロパティ Id によって DerivedClass のプロパティ Id を非表示にする方法を示しています。The example demonstrates how the property Id on DerivedClass can be hidden by the property Id on BaseClass when you use a restrictive access modifier such as protected or private. そのため、このプロパティに値を割り当てるときには、代わりに BaseClass クラスのプロパティが呼び出されます。Therefore, when you assign values to this property, the property on the BaseClass class is called instead. public によってアクセス修飾子を置き換えると、プロパティがアクセス可能になります。Replacing the access modifier by public will make the property accessible.

この例はまた、DerivedClassName プロパティの set アクセサー上の privateprotected などの制限されるアクセス修飾子が、アクセサーへのアクセスを防ぎ、アクセサーに割り当てたときにエラーが生成されることも示しています。The example also demonstrates that a restrictive access modifier, such as private or protected, on the set accessor of the Name property in DerivedClass prevents access to the accessor and generates an error when you assign to it.

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
*/

コメントComments

宣言 new private string Idnew public string Id によって置き換えた場合、次の出力を取得します。Notice that if you replace the declaration new private string Id by new public string Id, you get the output:

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

Name and ID in the derived class: John, John123

関連項目See Also

C# プログラミング ガイドC# Programming Guide
プロパティProperties
インデクサーIndexers
アクセス修飾子Access Modifiers