Ïîäðàçáèðàíå íà òèïà íà ïðîìåíëèâèòå
Ïðåäïîëàãàì, ÷å çàáåëÿçàõòå â ÷àñòòà
Ôèëòðèðàíå ñ LINQ è C# 3.0, ÷å èçïîëçâàõìå
êëþ÷îâàòà äóìà var âìåñòî ïîçíàòèòå
íè òèïîâå.  òàçè è ïîñëåäâàùàòà ÷àñò, ÷å îáÿñíèì ïîäðîáíî çàùî.
Êàòî ðàçðàáîò÷èöè íà C# çíàåì, ÷å ïðîìåíëèâè
ñå äåêëàðèðàò ïî òîçè íà÷èí
<èìå íà òèïà> <èìå íà ïðîìåíëèâà> [ = èíèöèàëèçàöèÿ];
|
Êúäåòî:
·
<èìå íà òèïà> - òèï íà ïðîìåíëèâàòà (string, int, SqlCommand èëè äðóãî èìå íà êëàñ),
êîéòî ïîêàçâà êàêâè äàííè ùå ñå ñúäúðæàò â äåêëàðèðàíàòà ïðîìåíëèâà
·
<èìå íà ïðîìåíëèâà> - íàèìåíîâàíèå íà ïðîìåíëèâàòà, êîåòî ùå èçïîëçâàìå ïî-êúñíî â êîäà.
Èìà ìíîãî ëèòåðàòóðà, êîèòî îïèñâàò êàê òðÿáâà äà ñå êðúùàâàò ïðîìåíëèâèòå è âñè÷êè
ñå ñúãëàñÿâàò, ÷å èìåòî òðÿáâà äà å ïîêàçâà çíà÷åíèåòî íà äàííèòå, êîèòî ñå ñúõðàíÿâàò
â ïðîìåíëèâàòà. (Ïðèìåð çà äîáðè èìåíà –
customerDiscount, databaseConnection. Ëîøè èìåíà –
alabala, rf0j;)
·
[ = èíèöèàëèçàöèÿ] – òîâà
å ÷àñòòà, êúäåòî ñå èçâèêâàò êîíñòðóêòîðèòå íà êëàñîâåòå èëè äàííèòå íà ïðîìåíëèâèòå.
Êàêòî, ñèãóðíî, ñå äîñåùàòå êëþ÷îâàòà äóìà
var çàìåñòâà èìåòî íà òèïà. Òîâà îçíà÷àâà, ÷å ïðîìåíëèâèòå äåêëàðèðàíè
ïî òîçè íà÷èí:
var text1
=
"This is text. ";
var num
= 12;
|
ñà èäåíòè÷íè íà ïðîìåíëèâèòå äåêëàðèðàíè ïî ïîçíàòèÿò íè íà÷èí:
string text1 =
"This
is text. ";
int num = 12;
|
Òóê ïî-íàïðåäíàëèòå ÷èòàòåëè ìîæå áè ñè çàäàâàò âúëíà îò âúïðîñè: Íå
å ëè ñúùîòî àêî âìåñòî var èçïîëçâàìå
object? Èëè Variant
çà äíèòå íà VB6 è COM?
À êàêâî ñòàíà ñ èäåÿòà çà ñèëíî òèïèçèðàíèòå ïðîìåíëèâè?
Îòãîâîðèòå íà òåçè âúïðîñè ùå ïîòúðñèì ñ âå÷å ïîçíàòèÿò íè èíñòðóìåíò
Reflector.
Íåêà äà äåêîìïèëèðàìå àñåìáëè, â êîåòî ñìå äåêëàðèðàëè ïðîìåíëèâè ñ var. Çà äà íàïðàâèì íåùàòà ïî-èíòåðåñíè ùå äîáàâèì
äåêëàðàöèÿ íà êëàñ:
var text1
=
"This is text. ";
var num
= 12;
var connection
=
new
SqlConnection("connection string here");
|
Ñëåä êîìïèëàöèÿòà (ñ êîìïèëàòîðà îò
LINQ Preview (May 2006)) è ðàçãëåæäàíå íà àñåìáëèòî ñ
Reflector, âèæäàìå ñëåäíîòî:
string text1 =
"This
is text. ";
int num = 12;
SqlConnection connection
=
new
SqlConnection("connection string here");
|
Èíòåðåñíî... Êàêòî áèõìå ãî íàïèñàëè è â C#2.0.
Òîâà îçíà÷àâà, ÷å êîìïèëàòîðà ðàçïîçíàâà äàííèòå è ïîñòàâÿ ïðàâèëíèÿò òèï. Òîâà
äåéñòâèÿ íå å ïî âðåìå íà èçïúëíåíèå (çà ðàçëèêà îò Variant) èëè ïî âðåìå íà ñúçäàâàíå
íà ïðèëîæåíèåòî (design time), à ïî âðåìå íà êîìïèëàöèÿ.
Ïî òàçè ïðè÷èíà, êîãàòî ñå èçïîëçâà var ïðîìåíëèâèòå
òðÿáâà äà ñå èíèöèàëèçèðàò íà ñúùèÿò ðåä.  ïðîòèâåí ñëó÷àé êîìïèëàòîðúò íÿìà äà
èìà ïðåäñòàâà çà äàííèòå, êîèòî ùå ñå ñúõðàíÿâàò. Òàçè ìàëêà õèòðèíà ñàìî ïðèâèäíî
ðàçìèâà èäåÿòà çà ñèëíî òèïèçèðàíè ïðîìåíëèâè.
Êàêòî èçãëåæäà òàçè íîâà åçèêîâà êîíñòðóêöèÿ âúâåæäà ãîëÿìî óëåñíåíèå
çà ðàçðàáîò÷èöèòå. Àêî ñè ïðåäñòàâèì ìåòîä ñ äâàäåñåòèíà ïðîìåíëèâè, äåêëàðèðàíè
ñ var, ùå å òðóäíî äà çàïîìíèì
òèïà íà âñÿêà åäíà îò òÿõ, à è íÿìà äà ìîæå äà ãî ïðî÷åòåì âåäíàòà, à òðÿáâà äà
ïîãëåäíåì è èíèöèàëèçèðàùàòà ñåêöèÿ. Òîâà áè íàïðàâèëî êîäà íå÷åòèì.
Äåêëàðèðàíåòî íà ïðîìåíëèâè ñ êëþ÷îâàòà äóìà
var
òðÿáâà äà ñòàâà ñàìî çà Àíîíèìíè
òèïîâå è êîëåêöèè âðúùàíè îò ìåòîäèòå íà LINQ.
Íåíóæíîòî èçïîëçâàíå ìîæå äà äîâåòå äî íàìàëÿâàíå êà÷åñòâîòî íà ïðîãðàìíèÿò êîä
è ïîñëåäâàùà ïðîìÿíà (maintenance).
Íà ïðúâ ïîãëåä òàçè ìàëêà êëþ÷îâà äóìè÷êà èìà ìíîãî ìàëúê ïðèíîñ. Íî
òîâà å ñàìî íà ïðúâ ïîãëåä, êàêòî ùå âèäèì â ñëåäâàùàòà ÷àñò –
Àíîíèìíè òèïîâå.
Àíîíèìíè òèïîâå
Õàðàêòåðíî çà ïðîãðàìíèòå åçèöè äî ìîìåíòà å ñëåäíèÿò íà÷èí çà ðàáîòà
ñ äàííè:
·
Äåôèíèðàíå íà òèïîâåòå äàííè – äåêëàðèðàíå íà êëàñîâå,
ñòðóêòóðè
·
Èíèöèàëèçèðàíå íà ïðîìåíëèâà îò òèï äåôèíèðàí â ïðåäõîäíàòà
òî÷êà
·
Èçïîëçâàíå íà äàííèòå – ïîïúëâàíå, ÷åòåíå, ïðîìÿíà íà
ñâîéñòâàòà íà îáåêòèòå.
Ïî òîçè íà÷èí ñå ñúçäàâàò îáåêòèòå â ò.íàð áèçíåñ ñëîé (business layer).
Êàêòî âèíàãè, îáà÷å, íåùàòà íå ñïèðàò äî òóê è ñëåäâà íå ìàëêî óñëîæíåíèå – äàííèòå
ñå ñúõðàíÿâàò â îòäåëåí ñëîé (SQL Server), êîéòî èçïîëçâà ðàçëè÷íè
íà÷èíè çà ñúõðàíåíèå íà äàííèòå. Òîâà íàëàãà ñâúðçâàíå ìåæäó äàííèòå â ñëîÿ çà ñúõðàíåíèå
(data tier) ñ áèçíåñ ñëîÿ. (Ïî-êúñíî ùå ðàçãëåäàìå ïîäðîáíî êàê
ñå îñúùåñòâÿâà òîâà ñâúðçâàíå ñ ïîìîùòà íà C# 3.0 è
Visual Studio Codename “Orcas”).
Íå áèâà äà ñå ïðåíåãðåãâà ìîìåíòà, â êîéòî ñå íàëàãà äà ñå ïðîìåíÿò
èçïîëçâàíèòå äàííè. Òîãàâà ñå íàëàãà ïðîìÿíà íà äåôèíèðàíèòå êëàñîâå è êîäà, êúäåòî
ñå èçïîëçâàò òå. À àêî ñà ñâúðçàíè ñúñ ñëîé çà ñúõðàíåíèå, òî òîãàâà ñå íàëàãàò
ïðîìåíè è â íåãî.
Çàáåëåæêà: Ïî-÷åñòî â ïðàêòèêàòà
ïðîìåíèòå â áèçíåñ ñëîÿ ñå íàëàãàò çàðàäè ïðîìåíè ñëîÿ ñ äàííè, íî çà öåëòà íà àáñòðàêöèÿòà
ðàçãëåæäàìå äâàòà âàðèàíòà – ñ è áåç ñëîé çà ñúõðàíåíèå.
Êàêòî ìîæå äà ñå ïðåäïîëîæè, èçèñêâàíåòî çà íÿêàêâà ïðîìÿíà â äàííèòå
íà ïðèëîæåíèåòî èçèñêâà ìíîæåñòâî ïðîìåíè â êîäà. Äîêàòî íå ìîæå äà ñå èçáÿãà (âñå
îùå) îò ïðîìÿíàòà íà ïîòðåáèòåëñêèÿ èíòåðôåéñ, â çàâèñèìîñò îò äàííèòå, òî àíîíèìíèòå
òèïîâå ïðåäîñòàâÿò óäîáåí è ëåñåí íà÷èí çà ðàáîòà ñ äàííè, êîèòî ÷åñòî ñå ïðîìåíÿò.
Çà ìîìåíòà ùå ïðåäñòàâèì êàê ñå ïîñòèãà òîâà, à ïðàêòè÷åñêàòà ïîëçà
ùå èçëåçå íàÿâå, êîãàòî ðàçãëåæäàìå LINQ â äåòàéëè.
Íåêà ñå âúðíåì íà ïðåäèøíèÿò ïðèìåð ñ êëàñà
Customer. Ñ ïîìîùòà íà íîâèòå åçèêîâè êîíñòðóêöèè ìîæå äà ñå
èíèöèàëèçèðà ïî òîçè íà÷èí:
Customer
cust = new
Customer
{ Id=1, Name="John Atanasov" };
|
Òîâà óëåñíÿâà ìíîãî èíèöèàëèçàöèÿòà íà îáåêòà, íî âñå îùå èçèñêâà äåêëàðàöèÿ
íà êëàñà Customer. Àêî èñêàìå äà
èçïîëçâàìå äàííè çà ñëóæèòåë áåç äà äåôèíèðàìå êëàñ çà íåãî òîâà ìîæå äà ñòàíå òàêà:
var employee
=
new
{Id=15, Name="Galin", Experience = 8, ManagerId=2};
|
è ìîæå äà èçïîëçâàìå òàêà ñúçäàäåíàòà è èíèöèàëèçèðàíà ïðîìåíëèâà â
ñúùèÿò ìåòîä:
Console.WriteLine(employee.Name);
|
èëè ïî íà÷èí, êîéòî íàìåðèì çà äîáðå. Òîâà å èçêëþ÷èòåëíî óäîáíî â
LINQ çàÿâêè, êîèòî ñîðòèðàò, ãðóïèðàò è âðúùàò íîâè ñòðóêòóðè îò äàííè.
Àêî òðÿáâà äà ñå äåôèíèðàò ïðåäâàðèòåëíî âñè÷êè êëàñîâå, òîâà áè îòíåëî ìíîãî âðåìå.
(âèæ ïðèìåðà îò Ãðóïèðàíå ñ LINQ è C# 3.0)
Íåêà äà íàâëåçåì â äúëáèíèòå íà òàçè ôóíêöèîíàëíîñò è äà âèäèì êàê òîâà
ñòàâà âúçìîæíî. Îòíîâî èçïîëçâàìå
Reflector è ïðè ðàçãëåæäàíå íà êîìïèëèðàíîòî àñåìáëè îòêðèâàìå ñëåäíèÿò
êëàñ:
[CompilerGenerated]
public
sealed
class <Projection>f__0
{
//
Methods
public <Projection>f__0();
public
override
bool Equals(object);
public
override
int GetHashCode();
public
override
string ToString();
//
Properties
public
int Experience
{
get;
set;
}
public
int Id {
get;
set; }
public
int ManagerId
{
get;
set;
}
public
string Name {
get;
set; }
//
Fields
private
int _Experience;
private
int _Id;
private
int _ManagerId;
private
string _Name;
}
|
Âå÷å ñòàâà ïî-ÿñíî, íàëè? Êàêòî èçãëåæäà îòíîâî êîìïèëàòîðà âúðøè íåïðèÿòíàòà
÷àñò îò ðàáîòàòà, êàòî ãåíåðèðà êëàñ, â çàâèñèìîñò îò äàííèòå/ñâîéñòâàòà
îò êîèòî èìàìå íóæäà. Ïî òîçè íà÷èí, êîãàòî ñå íàëîæè äà ïðîìåíÿìå êëàñà, ïðîñòî
òðÿáâà äà ïðîìåíèì èíèöèàëèçàöèÿòà (è èçïîëçâàíåòî ) íà êëàñà, íî íå òðÿáâà äà ñå
ãðèæèì äà ïðîìÿíà íà äåôèíèöèÿòà.
Êîìïèëàòîðà èìà è ìåõàíèçúì çà îïòèìèçàöèÿ, êîéòî èçïîëçâà âå÷å ãåíåðèðàíèÿò
êëàñ àêî èçïîëçâàìå äâå ïðîìåíëèâè ñ åäíàêâè ñâîéñòâà. Àêî ïðîìåíèì ñâîéñòâàòà,
îáà÷å, íîâ àíîíèìåí êëàñ ñå ãåíåðèðà.
Ñëåäâàùà ÷àñò: Àâòîìàòè÷íî èçãðàæäàíå íà ñâîéñòâà