共用方式為


非對稱存取子的存取範圍 (C# 程式設計手冊)

更新:2007 年 11 月

屬性或索引子的 getset 部分稱為「存取子」(Accessor)。根據預設,這些存取子具有相同的可視性 (或存取層級):即屬性或索引子所隸屬的層級。如需詳細資訊,請參閱存取範圍層級。不過,有時候限制對其中一個存取子的存取會很有用。通常,這會涉及限制 set 存取子的存取範圍,但同時讓 get 存取子保持為可公用存取。例如:

private string name = "Hello";

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

在此範例中,名為 Name 的屬性會定義 get 和 set 存取子。get 存取子會接收屬性本身的存取範圍層級 (在此案例中為 public),同時套用 protected 存取修飾詞至 set 存取子本身以明確限制此存取子。

在存取子上存取修飾詞的限制

在屬性或索引子上使用存取修飾詞必須遵從下列條件:

  • 在介面或明確介面成員實作上不能使用存取修飾詞。

  • 只有當屬性或索引子同時有 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。此範例將示範使用限制存取修飾詞時 (例如 protectedprivate),BaseClass 的 Id 屬性如何隱藏 DerivedClass 的 Id 屬性。因此,當您對這個屬性指派值時,會改為呼叫 BaseClass 類別的屬性。若您將存取修飾詞替換成 public,則屬性將可供存取。

這段程式碼同時也將示範限制存取修飾詞 (例如 private 或 protected) 套用在 DerivedClass 中 Name 屬性的 set 存取子時,會使存取子無法存取,並在指派時產生錯誤。

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 public string Id 取代宣告 new private 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# 程式設計手冊)