Laiendusmeetoditest lähemalt
05.12.2007 | Gunnar
C# 3.0 üks uuendusi on laiendusmeetodid ehk extension methods, mis võimaldavad olemasolevatele klassidele deklareerida juurde uusi meetode. Et säästa maailma uutest ja senisest võimsamatest apsakatest süsteemide tehnilise arhitektuuri loomisel, annan väikse süvatehnilise ülevaate sellest, milline näeb välja laiendusmeetodite kaardinate tagune.
Laiendusmeetodid, millest kirjutasin hiljuti kande Laiendusmeetodid (C# 3.0), on tegelikult IDE poolel aset leidev silmapete. Neid ei kompileerita olemasolevatele klassidele külge kuidagi vägisi, vaid kõik pöördumised laiendusmeetodite poole teisendatakse kompileerimisel vastava staatilise klassi meetodi kutseteks.
Eelmainitud kande põhjal loome klassi, mis lisab stringile meetodi Nl2Br(). Kood ise järgmine.
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace csharptest
{
public static class Ext
{
public static string Nl2Br(this string s)
{
return s.Replace("\r\n", "<br />")
.Replace("\n", "<br />");
}
}
class Program
{
static void Main(string[] args)
{
string s = "plah\r\nplah";
Console.WriteLine(s.Nl2Br());
Console.ReadLine();
}
}
}
IntelliSense näitab meile edaspidi, et selles projektis on stringil olemas nüüdsest uus meetod nimega Nl2Br.

Stringile deklareeritud laiendusmeetod Nl2Br() on näha ka IntelliSense-i poolt pakutavas omaduste ja meetodite loendis, mida kasutame
koodi kirjutamisel.
Kõik tundub olevat ju nii nagu naised saunas rääkisid - teed aga staatilise klassi, defineerid õigesti ära uue meetodi ja kohe see stringi küljes ongi. Tegelikult ei teki stringile juurde mitte midagi uut.
Mulle on alati tundunud huvitav see maailm, mis jääb lähtekoodist teisele poole kompilaatorit, sest see pole alati see, millisena me seda tajume. Nii ka seekord. Minu väiksele programmijupikesele vastav IL-kood on selline.
{
.entrypoint
// Code size 26 (0x1a)
.maxstack 1
.locals init ([0] string s)
IL_0000: nop
IL_0001: ldstr "plah\r\nplah"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call string csharptest.Ext::Nl2Br(string)
IL_000d: call void [mscorlib]System.Console::WriteLine(string)
IL_0012: nop
IL_0013: call string [mscorlib]System.Console::ReadLine()
IL_0018: pop
IL_0019: ret
} // end of method Program::Main
Nagu näeme ei ole laiendusmeetod kohe üldse stringi küljes. Kõik meie pöördumised laiendusmeetodi poole tõlgitakse kompileerimisel ümber hoopis pöördumisteks vastavale meetodile staatilises klassis.
Hoidke see hästi meeles, kui laiendusmeetode kasutate, sest see on puhtalt IDE poolne lõbu. Teisel pool kompilaatorit on asjad teisiti.
