niedziela, 15 czerwca 2014

[C#|Visual Studio] String, ToString()

Typ System.String znany także pod aliasem string towarzyszy nam przez całe nasze .NET-owe życie. W tym poście przedstawione zostaną pewne mniej znane konstrukcje, które mogą przydać się w codziennej pracy z C#.

W C# ciągi znaków są immutable, co oznacza, że nie można ich modyfikować. Każda operacja modyfikująca utworzy na stercie nową instancję. Typ System.String dziedziczy po object i implementuje takie interfejsy, jak IComparable, ICloneable, IConvertible, IEnumerable, IEquatable. Dodatkowo w C# można deklarować tzw. verbatim strings - ciągi znaków wewnątrz których każdy znak ma być traktowany jako część ciągu znaków - przed takim stringiem umieszczamy @.

String interning

Jest to technika optymalizująca zużycie pamięci w .NET. Polega ona na tym, że dla każdego ciągu znaków liczony jest hash i taki ciąg znaków wkładany jest do specjalnego słownika, gdzie kluczem jest właśnie ten hash. Słownik istnieje w obrębie całej AppDomain i podczas alokacji nowego string-a, jeżeli wyliczony hash znajduje się w słowniku, to instancja jest reużywana.

Konstruktory

Warto znać przeciążenia konstruktora. Poniżej przykład na to,  jak utworzyć ciąg 10 zer na 4 sposoby. Sposób wpisania literal-u wydaje się najprostszy, ale możemy to zrobić na inne, bardziej wygodne sposoby za pomocą konstruktorów.

char[] array = new char[10];
for (int i = 0; i < array.Length; i++)
    array[i] = '0';

char[] array2 = new char[12];
for (int i = 0; i < array2.Length; i++)
    array2[i] = '0';

Console.WriteLine(new string(array));
Console.WriteLine(new string(array2, 1, array2.Length -2));
Console.WriteLine(new string('0', 10));
Console.WriteLine("0000000000");

StringBuilder

W C# możemy sklejać stringi za pomocą operatora +. W pewnych sytuacjach (wiele sklejeń) jest on jednak bardzo niewydajny, dlatego zaleca się korzystać z klasy StringBuilder. Obiekt taki zawiera pole, które wskazuje na tablicę struktur typu Char. StringBuilder pozwala na manipulowanie taką tablicą. Jeżeli przekroczymy zaalokowane miejsce, to StringBuilder automatycznie skopiuje znaki i zbuduje nową tablicę. Wywołanie ToString spowoduje stworzenie nowego obiektu String na stercie i zwrócenie referencji do niego. Domyślna pojemność StringBuildera to 16 znaków. Jeżeli operacje wykonywane na nim próbują przekroczyć pojemność, to StringBuilder podwaja zaalokowane miejsce.

var random = new Random();
var sb = new StringBuilder();
var next = random.Next() % 100;
while (next % 2 == 0)
{
    sb.Append(next);
    next = random.Next() % 100;
}
Console.WriteLine(sb.ToString());

Instancyjne metody


var str = "Jambalaya";
//IEnumerable extension methods
Console.WriteLine(new string(str.Distinct().ToArray()));

//Walidacja
if(str.EndsWith("ya") && str.StartsWith("Ja") && str.Contains("ala"))
    Console.WriteLine("Matches");

Console.WriteLine(new string(str.Except("aya").ToArray())); //Jmbl
//traktuje aya jako IEnumerable<char>

//Analiza
Console.WriteLine(str.IndexOf('a'));
Console.WriteLine(str.IndexOfAny(new char[] {'a', 'J'}));
Console.WriteLine(str.LastIndexOf('a'));
Console.WriteLine(str.LastIndexOfAny(new char[] { 'l', 'y' }));

//Tworzenie nowych instancji
Console.WriteLine(str.Insert(3, "error")); //Jamerrorbalaya

//Uzupełnia podanym znakiem do zadanej długości (20), domyślnie spacja
Console.WriteLine(str.PadLeft(20, '_')); // ___________Jambalaya
Console.WriteLine(str.PadLeft(20)); //           Jambalaya

//3 oznacza maksymalną liczbę itemów
var items = str.Split(new char[] {'a'}, 3, 
    StringSplitOptions.RemoveEmptyEntries); //J,mb,laya
foreach (var item in items)
    Console.WriteLine(item);

str += "\n \t";
Console.WriteLine(str.Length); //12
//usuwa wszystkie biale spacje
str = str.Trim();
Console.WriteLine(str.Length); //9

Statyczne metody


var s1 = "me";
var s2 = "Mark";
Console.WriteLine(string.Compare(s1, s2)); //1

var s3 = string.Format("{0} and {1} went to school", s1, s2);
Console.WriteLine(s3);

Console.WriteLine(string.IsNullOrEmpty("")); //true
//drugi argument to params
Console.WriteLine(string.Join(",", s1, s2));

 

Numeryczne konwersje


float price = 99.99f;
Console.WriteLine("C - currency: " +
    price.ToString("C")); //99.99 zł
Console.WriteLine(price.ToString("C", 
    CultureInfo.CreateSpecificCulture("en-US"))); //$99.99

int num = 70;
Console.WriteLine("D - decimal: " + num.ToString("D4")); //0070

long number = 70000000000000000;
Console.WriteLine("E - exponential: " + 
    number.ToString("E")); // 7,000000E+016

Console.WriteLine("N - number: " +
    number.ToString("N")); // 70 000 000 000 000 000,00

double perc = 0.02;
Console.WriteLine("P - percent: " + perc.ToString("P")); //2,00%

int value = 1024;
Console.WriteLine("X - hexadecimal: " + value.ToString("X4")); //0040

Brak komentarzy:

Prześlij komentarz