Ograniczanie dostępności metody dostępu (Przewodnik programowania w języku C#)
Pobieranie i ustawianie części właściwości lub indeksatora są nazywane metodami dostępu. Domyślnie te metody dostępu mają ten sam poziom widoczności lub dostępu właściwości lub indeksatora, do którego należą. Aby uzyskać więcej informacji, zobacz poziomy ułatwień dostępu. Jednak czasami przydatne jest ograniczenie dostępu do jednego z tych metod dostępu. Zazwyczaj można ograniczyć dostępność set
metody dostępu, zachowując get
dostęp do metody dostępu publicznie. Na przykład:
private string _name = "Hello";
public string Name
{
get
{
return _name;
}
protected set
{
_name = value;
}
}
W tym przykładzie właściwość o nazwie Name
definiuje metodę get
i set
metodę dostępu. Akcesorium get
otrzymuje poziom ułatwień dostępu samej właściwości, w tym przypadku, public
podczas gdy set
akcesorium jest jawnie ograniczone przez zastosowanie modyfikatora dostępu chronionego do samego dostępu.
Uwaga
Przykłady w tym artykule nie używają automatycznie zaimplementowanych właściwości. Automatycznie zaimplementowane właściwości zapewniają zwięzłą składnię deklarowania właściwości, gdy niestandardowe pole zapasowe nie jest wymagane.
Ograniczenia dotyczące modyfikatorów dostępu dla metod dostępu
Używanie modyfikatorów dostępu we właściwościach lub indeksatorach podlega następującym warunkom:
- Modyfikatory dostępu nie mogą być używane w interfejsie ani w implementacji jawnej składowej interfejsu .
- Modyfikatory dostępu można używać tylko wtedy, gdy właściwość lub indeksator ma zarówno metody dostępu, jak
set
iget
. W takim przypadku modyfikator jest dozwolony tylko na jednym z dwóch metod dostępu. - Jeśli właściwość lub indeksator ma modyfikator przesłonięcia , modyfikator dostępu musi być zgodny z akcesorem przesłoniętego dostępu, jeśli istnieje.
- Poziom ułatwień dostępu w metodzie dostępu musi być bardziej restrykcyjny niż poziom ułatwień dostępu w samej właściwości lub indeksatorze.
Modyfikatory dostępu w zastępowaniu metod dostępu
Po zastąpieniu właściwości lub indeksatora przesłonięć metody dostępu muszą być dostępne dla zastępowania kodu. Ponadto dostępność zarówno właściwości/indeksatora, jak i jej akcesoriów musi być zgodna z odpowiednią właściwością/indeksatorem przesłonięć i jego metodami dostępu. Na przykład:
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; }
}
}
Implementowanie interfejsów
Jeśli używasz metody dostępu do implementowania interfejsu, metoda dostępu może nie mieć modyfikatora dostępu. Jeśli jednak zaimplementujesz interfejs przy użyciu jednego metody dostępu, takiego jak get
, drugi dostęp może mieć modyfikator dostępu, jak w poniższym przykładzie:
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 { }
}
}
Domena ułatwień dostępu dostępu
Jeśli używasz modyfikatora dostępu w metodzie dostępu, domena ułatwień dostępu metody dostępu jest określana przez ten modyfikator.
Jeśli nie użyto modyfikatora dostępu na metodzie dostępu, domena ułatwień dostępu jest określana przez poziom ułatwień dostępu właściwości lub indeksatora.
Przykład
Poniższy przykład zawiera trzy klasy, BaseClass
, DerivedClass
i MainClass
. Istnieją dwie właściwości w obiekcie BaseClass
i Name
Id
w obu klasach. W przykładzie pokazano, w jaki sposób właściwość może być ukryta przez właściwość Id
DerivedClass
Id
w BaseClass
przypadku używania restrykcyjnego modyfikatora dostępu, takiego jak chronione lub prywatne. W związku z tym podczas przypisywania wartości do tej właściwości właściwość jest wywoływana BaseClass
w zamiast tego. Zastąpienie modyfikatora dostępu przez publiczne spowoduje, że właściwość będzie dostępna.
W przykładzie pokazano również, że restrykcyjny modyfikator dostępu, taki jak private
lub , na set
metodzie dostępu do właściwości w programie DerivedClass
uniemożliwia dostęp do metody dostępu Name
w protected
klasie pochodnej. Generuje błąd podczas przypisywania do niego lub uzyskuje dostęp do właściwości klasy bazowej o tej samej nazwie, jeśli jest dostępny.
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
*/
Komentarze
Zwróć uwagę, że jeśli zastąpisz deklarację new private string Id
przez new public string Id
, otrzymasz dane wyjściowe:
Name and ID in the base class: Name-BaseClass, ID-BaseClass
Name and ID in the derived class: John, John123