Nutylimųjų savybių ieškant

Pastaba: šis straipsniukas pavyzdžiams naudoja C#

Nutylimosios savybės leidžia objektui tiesiogiai priskirti reikšmes. Jas dalinai palaiko .Net ir C#, bet ar mes negalime padaryti geriau? Jas realizuosime panaudodami indeksuotojus (indexers), operatorių pertekliškumą (overload) ir betarpiškus operatorius.

Nutylimųjų savybių idėja atrodo keista, nes, tarytum, jai nėra vietos objektiškai orientuotame programavime. Tačiau jos leidžia patogius užrašus, pvz.,
oObjektas=oObjektas+5 vietoje griozdiško
oObjektas.Kiekis.value= oObjektas.Kiekis.value+5

Netgi galima, kaip nutylimąją savybę, kviesti metodus, pvz., parašyti int r=Rnd; vietoje int r=Rnd.nextiot();

Aišku, kyla nemaža problema, kaip atskirti o Objektas1=oObjektas2; ir oObjektas1=kiekis;

Vienintelis būdas yra realizuoti taisyklę, panaudojančią nuorodos tipo priskyrimą, kai priskiriamas kiekybė yra sulyginama su klase, nutylimosios savybės priskyrimą, kai ji sulyginama su nutylimąja savybe ir sukelti išimtį visais kitais atvejais.

Kaip iliustraciją, paimkime steko klasės C# realizaciją (paprastumo dėlei, skirtą tik sveikiems skaičiams) tokią, kad klasę būtų galima naudoti išraiškose, t.y., kad
stekas=stekas*2+stekas+5;
reikštų
stekas.push(stekas.pop()*2+stekas.pop()+5);

Bazinė steko klasė su push ir pop metodais būtų

public class stekas {

   private int [] Talpykla = new int [10];
   private int pos = 0;

   public void push (int duomuo) {
      Talpykla[pos++] = duomuo;
   }

   public int pop () {
      return Talpykla[--pos];
   }

}
Cup with C source

Jos panaudojimas labai paprastas:

stekas oStekas = new stekas();
oStekas.push(10);
Console.WriteLine(oStekas.pop());

Žinoma, tas pačias operacijas galima realizuoti ne kaip metodus, o kaip savybes:

public int value {
   get { return this.pop(); }
   set { this.push(value); }
}

Ir panaudojant taip:

 oStekas.value = 20;
 Console.WriteLine(oStekas.value);

Kadaise „Visual Basic“ turėjo nutylimąją savybę, tačiau vėliau ji buvo pašalinta, taikantis prie C#. Mums abiejose kalbose belieka tik pasinaudoti indeksuotoju – artimu nutylimosioms savybėms ir kartu tolimu. Indeksuotojas leidžia objektą traktuoti tarsi nutylimąją savybę, kuri yra masyvu – taigi galime užrašyti:
oObjektas[k]=duomuo;

Tačiau yra ir vienas apribojimas – negalime „numesti“ [k]. O indeksuotoją sukurti galime tiesiog apibrėždami savybę this:

public int this[int nx] {
   set { this.push(value); }
}

Dabar galima užrašyti taip: oStekas[0]=20; Console.WriteLine(oStekas[0]);

Tačiau vis dar nepasiekėme nutylimųjų savybių. Reiktų pasinaudoti priskyrimo operatoriaus pertekliškumu, tačiau, skirtingai nuo C++, C# to padaryti neleidžia. Tačiau galima priskirti perteklinį veiksmą + operatoriui, o kartu ir tokiai kombinacijai kaip +=. Tačiau pamatysime, kad ir tai nėra per daug naudinga.

static public int operator + (stekas S, int d) {
   return S.pop()+d;
}

Tada galime užrašyti: oStekas.push(40); Console.WriteLine(oStekas+10);
ir atsakymas bus 50. Tačiau norint panaudoti 10+oStekas, turėsime papildomai aprašyti:

static public int operator + (int d, stekas S) {
   return S.pop()+d;
}

Tačiau tai vis dar neleis užrašyti taip: oStekas=10; arba int v=oStekas;
nes pertekliniai veiksmai neleidžiami priskyrimo operatoriui. Tačiau galime rašyti taip:

int v=1;
v+=oStekas;
Console.WriteLine(v);

Nes += išplečiamas į v=v+oStekas;
ir + pertekliškumas veikia korektiškai.

Tiesioginė konversija

Yra įvairių priemonių dalinai realizuoti nutylimąsias savybes. Tarkim, nesunku padaryti, kad veiktų toks priskyrimas:
int duomuo=oStekas;
Tam tereikia apibrėžti tiesioginio konvertavimo operatorių, pvz.,

public static implicit operator int (stekas S) {
   return S.pop();
}

Tačiau tai neleis užrašyti: oStekas=90;
Tai susiję su tuo, kad mažai žinoma apie kairiąją priskyrimo operatoriaus pusę. Vienintelė išeitis tėra sukurti naują steko objektą, su push jame įsiminti reikšmę ir tada ją gražinti priskiriant oStekas. Tai sukelia steko būsenos pakeitimą, kas nėra reikalinga. Kažin, ar yra kitas sprendimas?

Ankstesnės "Advanced HTML" skyrelio temos:
JavaScript kitoniškumas
Pelė uodega švystelėjo...
Sveikųjų skaičių žaidimai
CGI.pm biblioteka: sausainiai
Ką delne mums neša HTML 4.0?
MS SQL užklausų rezultatų puslapiavimas
Kaip valdyti piešinių pakrovimo tvarką
Kaip lankytoją nukreipti į kitą WWW puslapį
Viešojo rakto kriptografija
Tikroji Interneto pabaiga
Įlįskite į lankytojų kailį
Vaizdi rašysena - VB Script
ASP patarimų liūnas
Tiesa apie REST

JavaScript pradmenys
AWK kalba - sena ir nuolat aktuali
Viešojo rakto kriptografija
Vartiklis