Кратко съдържание



страница62/73
Дата21.07.2018
Размер9.03 Mb.
#76887
1   ...   58   59   60   61   62   63   64   65   ...   73

Типът System.Char


Типът System.Char в .NET Framework е стойностен тип и позволява съхра­нението на една 16-битова Unicode стойност. В езика C# примитивният тип char е еквивалентен на типа System.Char.

В повечето случаи един символ може да се представи с една инстанция на типа char, но това не винаги е така. В .NET Framework символите с Unicode номер, по-голям от 65536, се представят като последователност от две инстанции на System.Char.


Методи за класификация на символите


Типът System.Char притежава статичен метод GetUnicodeCategory(), кой­то връща информация за съответния знак (дали е малка буква, главна буква, символ за валута, математически символ и т.н.). Останалите мето­ди, служещи за класифицирането на символите, са дадени в таблицата:

Метод

Описание

IsLetter()

Проверка дали знакът е буква (letter). Букви са не само латинските A..Z, но и буквите от други азбуки, като например "Ъ", "Σ" и "".

IsDigit()

Връща true ако знакът е цифра.

IsWhiteSpace()

Връща true ако знакът е за празно място (ин­тервал, табулация, символ за нов ред и др.).

Методите IsLetter(), IsDigit(), IsSeparator() и IsWhiteSpace() връ­щат са реализирани чрез вътрешно извикване на GetUnicodeCategory().

Методи за смяна на регистъра


Конвертирането на знак към главни или малки букви става чрез извик­ване на статичните методи Char.ToUpper() и Char.ToLower(). Резултатът от извикването на двата метода зависи от информацията за културата. Тя може да бъде подадена като параметър, а по подразбиране се използва текущата. Ролята на културата ще бъде дискутирана малко по-нататък.

Символни низове в .NET Framework


В .NET Framework символните низове (strings) представляват последо­ва­телност от Unicode знаци, записани в кодиране UTF-16. Това позволява на програ­мистите с лекота да използват в своите приложения едновре­менно различни езици.

За символните низове в .NET се използва системният тип System.String. Той представлява неиз­менима (immutable) последователност от символи (ин­станции на System.Char).

Както всички типове в .NET Framework, така и System.String е наследник на System.Object. Типът System.String е референтен и неговите инстан­ции се съхраняват в динамичната памет. Той е обезопасен за много­нишково изпълнение.

В езика C# типът System.String може да се изписва съкратено чрез неговия псевдоним, запазената дума string:



string s = "Няма бира!";

Поради причини, свързани с производителността, архитектите на .NET Framework са интегрирали символните низове тясно с CLR.

Веднъж създадени инстанциите на типа String не могат повече да бъдат променяни. При нужда от промяна на символни низове в хода на програ­мата, тази особеност може да доведе до намалена производителност. За справяне с този проблем при динамична обработка на символни низове се използва класът System.Text.StringBuilder, на който ще се спрем малко по-късно.


Символните низове и паметта


При работа с методи, които модифицират символните низове, ние не променяме самия символен низ, а създаваме нов, в който биват отразени промените.

Нека да разгледаме следния примерен код, който демонстрира работата със символни низове:



static void Main()

{

string s = "Няма бира!";



string s2 = s;

s = "Докараха бира!";

s += " ... и трезви няма.";

Console.WriteLine("s = {0}", s);

Console.WriteLine("s2 = {0}", s2);

}


В началото дефинираме променлива s от референтния тип System.String, като едно­временно с това й задаваме стойност "Няма бира!":

string s = "Няма бира!";

В този случай s е указател (референция), който сочи към определено място в динамичната памет, където е записана стойността "Няма бира!".

На следващия ред създаваме втори символен низ, който инициализираме със стойността на първия:



string s2 = s;

В този случай вече имаме два указателя (s и s2), които сочат към едно и също място в паметта:

При третото действие задаваме нова стойност за s, при което се създава нов обект в динамичната памет:



s = "Докараха бира!";

След изпълнението на този ред s съдържа указател, който сочи към друго място в паметта, защото стойността е променена:

Следва долепване на низа " ... и трезви няма." към стойността на низа s:



s += " ... и трезви няма.";

Понеже низовете в .NET Framework са неизменими, тази операция създава нов обект в динамичната памет и записва в него резултата от долепва­нето. Старата стойност на s остава в динамичната памет като нерефери­ран от никого обект, който ще бъде освободен при следващото почистване на паметта:


Класът System.String


Класът System.String е основополагащ за работата със символни низове в .NET Framework. Нека се запознаем в детайли с по-важните методи и свойства на System.String.

Правила за сравнение на символни низове


Методите и свойствата на класа System.String могат да бъдат разделени на числени и лексикографски. Числените методи, изпълнявани върху сим­волен низ, действат върху индекса (поредния номер в низа) на всеки знак. Лексикографските операции действат върху стойността на низа, съобраз­но избраната култура, форматиране и правила за парсване.

Много от числените и лексикографските операции се базират на прави­лата за сортиране. .NET Framework подържа правила за сортиране по дума, низ и последователност на Unicode символите.

Сортирането на думи (word sorting) е чувствително към културата лекси­кографско сравнение на низове. На Unicode символите, които не са букви или цифри, се приписва определена стойност – тегло. Например символът тире "-" може да има нулево тегло, така че низовете "coop" и "co-op" да бъдат равни. Така два низа могат да бъдат логически равни, дори и знаковите им последователности да не са еднакви. Например ако изпол­зваме немска култура, низовете "Straße" и "Strasse" ще са еквивалентни.

Сортирането на низове (string sorting) по същество е същото като сорти­рането по думи, с изключение на факта, че всички небуквени и нециф­рени символи предхождат всички останали.

При сортирането по последователност на Unicode символите (ordinal sorting) два низа се сравняват по числената стойност (поредния номер в Unicode стандарта) на всеки символ в низа.

Процедурите за сравнение и процедурите за търсене в низове по под­разбиране са чувствителни към главни и малки букви. Те използват култу­рата, асоциирана към текущата нишка, освен ако изрично не е указана друга. По дефиниция всеки символен низ, включително и празният (""), е по-голям от стойността null. При сравнение на две стойности null, те се считат за равни.

При системи, в които се използва критично за сигурността сравнение на низове, трябва да се избере подход, при който културата не застрашава коректния резултат от сравнението. Грешка би могла да се получи, когато текущата култура на потребителя е различна от тази на приложението. Решение на проблема е употребата на инвариантна култура (на която ще се спрем подробно след малко).

Добра практика е да се използва инвариантна култура за съхранение на данни, които не се извеждат директно на потребителя. Данни за валута и дати могат да се съхраняват с инвариантна култура и при визуализи­рането им в приложението да бъдат форматирани по подходящ начин. Така няма да има несъответствия при изпълнението на програмата от потребители с различни настройки на културата.


Методи и свойства на System.String


По-важните свойства на класа за работа с низове са Length, което връща броя на символите в инстанцията на низа, и Chars[int], което връща символа на зададена позиция в низа. В C# вместо свойството Chars[int] се използва за индексатор на низа this[int], който също връща символа на зададената позиция.



Индексирането на символите в низовете в .NET Framework започва от 0. Първият символ в даден низ s се намира на позиция 0, а последният – на позиция s.Length-1.

Методи за сравнение на низове


За сравнение на низове се използва методът Compare(), който е преде­финиран с различни по брой и/или тип параметри. При Compare() срав­не­нието на низовете е лексикографско, като се взима предвид текущата културата. Като параметър може да бъде зададена специфична култура или инвариантност спрямо културата. Ако целта на сравнението е да бъдат сортирани низове, то трябва да укажем да се прави разлика между малки и главни букви. В противен случай два низа, съдържащи съответно малка и главна буква, се считат за равни и при всяко изпълнение на програмата низовете могат да бъдат сортирани в различен ред.

За разлика от метода Compare(), статичният метод CompareOrdinal() не отчита културата. При него се сравняват само Unicode стойностите и той връща равенство, ако двата низа съдържат една и съща последователност от знаци. Тъй като малките и главните букви имат различни Unicode стойности, то CompareOrdinal() е чувствителен към разлика в низовете, дължаща се на малки и главни букви.

Методите Compare() и CompareOrdinal() връщат положително, отрица­телно число или 0 в зависимост дали първият аргумент е съответно по-голям, по-малък или равен на втория. Ето един пример, който илюстрира лексикографско сравнение на низове:

string s1 = ".NET Framework";

string s2 = ".NET Platform";

int compareResult = String.Compare(s1, s2);

Console.WriteLine(compareResult); // Prints -1



В примера не е указано какво култура да бъде използвана, заради което се подразбира текущата.

Друг метод за сравнение на низове е Equals(). Преди да извърши сравнението на два низа чрез вътрешно извикване на методът CompareOrdinal(), този метод проверява референциите на двата низа. Ако референциите сочат към един и същ обект в паметта, Equals() връща true без да прави по-нататъшна проверка. Това прави методът изключително бърз при използване на интерниране на низове, с което ще се запознаем по-късно.

Методът Equals() може да бъде извикван с различен тип и брой пара­метри. Той приема един или два параметъра, които могат да бъдат низове, произволен обект или инстанция на класа StringBuilder (който ще раз­гледаме след малко).

Освен методите за сравнение на низове се използват и операторите == и !=. Двата оператора са имплементирани на базата на метода Equals() на System.String и са чувствителни към малки и главни букви.


Търсене на съвпадения в началото и в края


StartsWith() и EndsWith() са методи, които проверяват дали дадената инстанция на класа String започва или завършва със зададения като параметър низ. StartsWith() връща true, ако зададеният низ се среща в началото на инстанцията или ако сме задали празен низ, и false в противен случай. EndsWith() връща true, ако инстанцията на обекта от класа System.String завършва със зададения като параметър низ или ако сме задали празен низ. За целта методът сравнява параметъра с подниз, извлечен от края на текущата инстанция със същата дължина, като пара­метъра. И двата метода извършват търсене на дума (word search), изпол­звайки текущата култура и са чувствителни към малки и главни букви.

Работа с низове – прост пример


Следният примерен код илюстрира индексиране на низ, слепване на ни­зове и сравняване на низове с оператор, както и метода StartsWith():

static void Main()

{

string s = "Няма бира!";



for (int i=0; i

{

Console.WriteLine("s[{0}] = {1}", i, s[i]);



}
string s2 = "Няма " + "бира!";

if (s == s2) // true

{

// Both strings have equal values



Console.WriteLine("s == s2");

}
if (s.StartsWith("Няма")) // true

{

Console.WriteLine("Няма, но ще докарат!");



}

}


Ето резултата от изпълнението на примера:


Извличане на подниз


За извличане на подниз в класа System.String е предвиден метод Substring(). Той може да бъде извикан с един или два параметъра от тип Int32, които задават съответно началото и дължината на подниза. Ако подаденият начален индекс е равен на дължината на низа и вторият параметър е 0 или липсва, то върнатият подниз ще е празен. Ако параметърът, указващ началото, е по-малък от 0 или по-голям от дъл­жината на низа, се получава изключение ArgumentOutOfRangeException. Това изключение ще получим и ако подадената дължина е по-голяма от дължината на низа. Отново ще напомним, че индексирането на символите в низа започва от 0.

Търсене в низ


Методът IndexOf() връща позицията на първото срещане на посочения като параметър низ в текущия низ. Ако низът не бъде открит, върнатата стойност е -1. Този метод също е предефиниран по сигнатура и може да приеме като параметър String или Char обект за търсене. Може да бъде зададена и специфична област от низа, в която да се търси зададения подниз или символ. Сравнението при търсене на подниза е чувствително към малки и главни букви, но е нечувствително към културата.

Аналогично методът LastIndexOf() връща позицията на последното сре­щане на зададения низ в низовия обект или -1 ако няма съвпадение.


Търсене в низове – пример


За да илюстрираме търсенето в низове, ще дадем за пример следния код, показващ действието на мето­дите Substring() и IndexOf():

string s = "Няма бира!";
string beer = s.Substring(5, 4); // beer = "бира"

Console.WriteLine(

"\"{0}\".Substring(5,4) is \"{1}\".", s, beer);

// Result: "Няма бира!".Substring(5,4) is "бира".


int beerIndex = s.IndexOf("бира"); // 5

Console.WriteLine(

"The index of \"{0}\" in \"{1}\" is {2}.",

"бира", s, beerIndex);

// Result: The index of "бира" in "Няма бира!" is 5.
int vodkaIndex = s.IndexOf("водка"); // -1

Console.WriteLine(

"The index of \"{0}\" in \"{1}\" is {2}.",

"водка", s, vodkaIndex);

// Result: The index of "водка" in "Няма бира!" is -1.

Разделяне и слепване на низове


За разделяне и слепване на низове в класа System.String са предвидени няколко метода. Методът Split() разделя низовия обект на множество от поднизове по зададен като параметър масив от разделителни символи. Поднизовете се връщат в масив от низове (string[]).

Методът Join() на класа String служи за слепване на низове. При зададен разделител и масив от низове, той създава един обединен низ, като между елементите от масива постави разделителя.


Допълнителни ресурси при визуализация на низове


При визуализиране на низове в .NET често се използва методът Format(). Той замества всеки форматиращ идентификатор в низа със стойностите на посочените обекти. Има възможност за поставяне на няколко форматиращи идентификатора, както и задаване на специфична култура за визуализацията на стойностите. На форматиращите низове ще се спрем в детайли след малко.

За подравняване на низове при визуализация се използват методите PadLeft() и PadRight(). PadLeft() подравнява низа като отляво оставя посочения брой празни места или друг зададен Unicode символ. Аналогично PadRight() визуализира низа като оставя отдясно зададен брой празни места или зададения символ.


Разделяне, слепване и визуализация на низове - пример


След като се запознахме с методите Split(), Join() и Format() ще използваме следния пример, за да демонстрираме работата с тях:

string wisdom = "Петър плет плете, през три пръта " +

"преплита. Подпри, Петре, плета!";

string[] words = wisdom.Split(' ', ',', '.', '!');

foreach (string w in words)

{

if (w != "")



{

Console.Write("{0} ", w);

}

}

Console.WriteLine();



// Result: Петър плет плете през три пръта преплита Подпри Петре плета
string[] drinks = {"бира", "ракия", "вино", "водка"};

string wordsList = String.Join(", ", drinks);

Console.WriteLine("Остана само: {0}.", wordsList);

// Result: Остана само: бира, ракия, вино, водка.


string nonsense = String.Format(

"Доказано е, че {0} + {1} = {2}, но само при " +

"достатъчно големи стойности на {3}.", 2, 2, 5, 2);

Console.WriteLine(nonsense);

// Result: Доказано е, че 2 + 2 = 5, но само при достатъчно големи стойности на 2.
string formattedDate = String.Format(

"Днес е {0:d.MM.yyyy} г.", DateTime.Now);

Console.WriteLine(formattedDate);

// Result: Днес е 2.08.2004 г.


const int SIZE = 15;

string formattedName = "Бай Иван".PadLeft(SIZE, ' ');

string formattedSum = "131.7 лв.".PadLeft(SIZE, '0');

Console.WriteLine("Вашето име : {0}", formattedName);

Console.WriteLine("Вие дължите: {0}", formattedSum);

// Result:

// Вашето име : Бай Иван

// Вие дължите: 000000131.7 лв.



Понеже в примера не е указана култура при форматирането на датата, се използва културата по подразбиране, в случая българската култура.

Модифициране на низове


Класът System.String притежава и някои методи за модификация на ни­зове. Както споменахме, стойността на обект от тип string е непроме­няема и затова всички тези методи водят до създаване на нов обект, в който връщат модифицираният низ. Използването на тези методи е подхо­дящо при началната инициализация на низов обект, но не е препоръчи­телно да се използват многократно в цикъл, защото това ще намали зна­чително производителността.

Методът Trim(…) премахва зададените символи от началото и края на низа. Извикан без параметър методът премахва празните места в началото и края на низа. Предефинираният метод може да бъде извикан с група от символи, които да бъдат премахнати.

Методите за смяна на главни с малки букви и обратно са ToLower() и ToUpper(). За целта те използват текущата култура, ако не бъде зададена изрично друга.

За вмъкване на низ в низовия обект се използва методът Insert(…). Като параметри му се задават позицията в низовия обект, където да бъде вмъкнат подниз, и подниза, който да бъде вмъкнат. Грешки възникват при изпълнение на C# код ако е зададен null като подниз за вмъкване или позицията за вмъкване е извън границите на низовия обект.

Класът System.String предлага и метод за премахване на зададен брой символи от указана позиция в низовия обект. Това става с метода Remove(…). При работа с този метод трябва да внимаваме параметрите да не излизат извън дължината на низовия обект, защото това води до възникване на изключение.

Методът Replace(…) служи за заместване на зададен низ със зададен друг низ. Това заместване се извършва при всяко срещане на подадения като параметър низ в низовия обект.


Модифициране на низове – пример


Ще илюстрираме работата с методите Trim(…), ToUpper(), Insert(…), Remove(…) и Replace(…) чрез следния пример:

string example = ", мента, мастика, коняк.";

string trimmed = example.Trim(',', '.', ' ');

Console.WriteLine(trimmed);

// Result: мента, мастика, коняк


String upDemo = trimmed.ToUpper();

Console.WriteLine(upDemo);

// Result: МЕНТА, МАСТИКА, КОНЯК
string insertDemo = upDemo.Insert(7, "боза, ");

Console.WriteLine(insertDemo);

// Result: МЕНТА, боза, МАСТИКА, КОНЯК
string removeDemo = insertDemo.Remove(11, 9);

Console.WriteLine(removeDemo);

// Result: МЕНТА, боза, КОНЯК
string replaceDemo = removeDemo.Replace(", ", " + ");

Console.WriteLine(replaceDemo);



// Result: МЕНТА + боза + КОНЯК

Методи на System.String


Ще обобщим накратко действието на по-важните методи на класа String:

Метод

Описание

Compare(…)

Сравнява два низа лексикографски, като се съо­бразява с особеностите на културата.

CompareOrdinal(…)

Сравнява два низа като взима числената стойност на всеки символ от Unicode таблицата.

CompareTo(…)

Сравнява низовия обект със зададен като пара­метър друг низ.

Concat(…)

Слепва два или повече низа или стойности на низови обекти.

Copy(…)

Създава нова инстанция на обект от тип string със същата стойност.

CopyTo(…)

Копира зададен брой символи от определена об­ласт в низа и ги записва в масив.

EndsWith(…)

Определя дали низът завършва със зададения низ.

Equals(…)

Определя дали два низови обекта имат една и съща стойност.

Format(…)

Замества всеки форматиращ идентификатор със стойността на зададен обект.

GetEnumerator()

Връща обект, който може да обхожда отделните знаци на низовия обект.

IndexOf(…)

Връща позицията на първото срещане на зададен низ в низовия обект.

IndexOfAny(…)

Връща позицията на първото срещане на някои от символите, зададени в масив като параметър.

Insert(…)

Вмъква зададен низ на зададена позиция.

Intern()

Ако вече не е добавен, добавя низ в "Intern pool" таблицата и връща системния указател към него. Ще разгледаме този метод в секцията "Интерни­ране на низове".

IsInterned()

Връща указател към зададен низ. Ако низът не е в "Intern pool" връща null.

Join(…)

Слепва елементите на зададен масив от низове като между всеки два елемента поставя зададен разделител.

LastIndexOf(…)

Връща позицията на последното срещане на зада­ден низ в низовия обект.

LastIndexOfAny(…)

Връща позицията на последното срещане на някои от символите зададени в масив като параметър.

PadLeft(…)

Подравнява низа като добавя отляво зададен брой празни места или символи.

PadRight(…)

Подравнява низа като добавя отдясно зададен брой празни места или символи.

Remove(…)

Изтрива зададен брой символи от низа, започвайки от зададена позиция.

Replace(…)

Замества всички срещания на зададен низ със стойността на зададен друг низ в нов обект от тип string.

Split(…)

Разделя низа на поднизове по зададен разделител и записва получените поднизове в низов масив.

StartsWith(…)

Определя дали низът започва със зададен низ.

Substring(…)

Връща подниз от низовия обект.

ToCharArray()

Връща съдържанието на низа във вид на масив от символи (char[]).

ToLower()

Сменя регистъра на низа към малки букви.

ToUpper()

Сменя регистъра на низа към малки букви.

Trim(…)

Премахва зададени символи от началото и края на низа.

TrimEnd(…)

Премахва зададени символи от края на низа.

TrimStart(…)

Премахва зададени символи от началото на низа.



Сподели с приятели:
1   ...   58   59   60   61   62   63   64   65   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница