[ Pobierz całość w formacie PDF ]
protected set { name = value; } } public virtual void ChangeName(string name) { // tu operacje aktualizujące rekordy Name = name; // odwołanie do prywatnego akcesora } } class Program 68 Rozdział 1: C# 2.0 { static void Main(string[] args) { Employee joe = new Employee("Joe"); // inne operacje string whatName = joe.Name; // działa // joe.Name = "Bob"; // odmowa kompilacji joe.ChangeName("Bob"); // działa Console.WriteLine("imię joe'a: {0}", joe.Name); } } } Wynik: imię joe'a: Bob Jak to działa? Projekt klasy Employee (pracownik) sygnalizuje, że ciąg imienia pracow- nika ma być prywatny. Ale programista przewidział, że kiedyś przyjdzie mu wstawiać dane o pracownikach do bazy danych, więc udostępnił imię za pośrednictwem właściwości Name. Pozostałe klasy programu powinny mieć możliwość odwoływania się do Name, ale jedynie w odwołaniach niemodyfikujących. Zmiana wartości pola może się odbywać jedynie za pośrednictwem jawnego wywołania metody ChangeName. Metoda została oznaczona jako wirtualna w przyszłych klasach pochodnych zmiana imienia pracownika będzie się pewnie wią- zała z dodatkowymi operacjami. Zachodzi tu potrzeba udostępnienia akcesora set, ale tylko metodom klasy Employee i metodom jej klas pochodnych. Ograniczenie takie można wy- egzekwować modyfikatorem dostępu dla akcesora set: protected set { name = value; } A co& & z ograniczeniami odnośnie stosowania modyfikatorów dostępu? Otóż modyfikatorów tych nie można stosować wobec interfejsów i jawnych implementacji składowych interfejsów. Modyfikatory dostępu można sto- sować jedynie wtedy, kiedy właściwość obejmuje oba akcesory (get i set); można nimi przy tym opatrywać tylko jeden z akcesorów. Ograniczanie dostępu do właściwości 69 Poza tym modyfikator musi ograniczać, a nie rozszerzać dostępność. Nie można więc zadeklarować właściwości ze słowem protected, a potem za pomocą modyfikatora oznaczyć akcesor get jako dostępny publicznie. Więcej informacji O właściwościach i modyfikatorach dostępu do właściwości traktuje artykuł MSDN publikowany pod adresem http://msdn.microsoft.com/library/de- fault.asp?url=/library/en-us/csref/html/vclrfPropertiesPG.asp. Elastyczność delegacji z kowariancją i kontrawariancją Nowa specyfikacja języka C# zezwala na określanie metod delegacji z ty- Kowariancja pozwala pem wartości zwracanej, będącej pochodną (bezpośrednią bądz pośrednią) na stosowanie typu zwracanego określonego w definicji delegacji; operacja taka nosi mia- z delegacjami metod no kowariancji. Chodzi o to, że jeśli definicja delegacji zakłada zwracanie zwracających wartości typu wartości typu Mammal (ssak), to delegację tę można zastosować do metody będącego pochodną zwracającej wartość typu Dog (pies), o ile Dog jest pochodną Mammal, a także (bezpośrednią lub pośrednią) do metody zwracającej wartość typu Retriever, o ile Retriever to pochodna typu zwracanego typu Dog, a ten jest pochodną Mammal. określonego w definicji delegacji. Analogicznie dozwolone jest przekazywanie sygnatury metody delegacji, w której typy parametrów są pochodnymi typów parametrów zdefiniowa- nych w delegacji. To z kolei określa się mianem kontrawariancji. Chodzi o to, że jeśli definicja delegacji wymaga podania metody przyjmującej pa- rametr typu Dog, to można ją użyć z metodą przyjmującą parametr typu Kontrawariancja Mammal (znów pod warunkiem że Dog to pochodna Mammal). pozwala na stosowanie Jak to zrobić? z delegacjami metod przyjmujących Kowariancja i kontrawariancja zwiększają elastyczność w zakresie doboru parametry typu będącego typem metod dla delegacji. Zastosowanie kowariancji i kontrawariancji ilustruje bazowym listing 1.10. (bezpośrednim lub pośrednim) typu parametru określonego w definicji delegacji. 70 Rozdział 1: C# 2.0 Listing 1.10. Stosowanie kowariancji i kontrawariancji #region Using directives using System; using System.Collections.Generic; using System.Text; #endregion namespace CoAndContraVariance { class Mammal { public virtual Mammal ReturnsMammal() { Console.WriteLine("Ssak"); return this; } } class Dog : Mammal { public Dog ReturnsDog() { Console.WriteLine("Pies"); return this; } } class Program { public delegate Mammal theCoVariantDelegate(); public delegate void theContraVariantDelegate(Dog theDog); private static void MyMethodThatTakesAMammal(Mammal theMammal) { Console.WriteLine("W metodzie akceptującej ssaki"); }
[ Pobierz całość w formacie PDF ]
|