Paweł Łukasiewicz
2019-05-02
Paweł Łukasiewicz
2019-05-02
Udostępnij Udostępnij Kontakt
Wprowadzenie

Zanim przejdziemy do części właściwej artykułu skupimy się na małym przypomnieniu obecnej wiedzy. Język C# wspiera, tzw. verbatim string literals. Identyfikatory dosłownego wyrażenia zaczynają się od znaku: @, otwartego oraz kończącego cudzysłowia. Ich użycie polega na dosłownej interpetacji następującego ciągu znaków – znaki sekwencji ucieczki nie są brane pod uwagę.

Pierwotnie używaliśmy zapisu ("\\"), aby uniknać interpretacji znaków sekwencji ucieczki. Dosłowny zapis powodował pojawienie się błędu w kompilatorze:

// W poniższym przypadku nasz kompilator informował nas o poniższym błędzie:
// Unrecognized escape sequence – błąd wyświetlany trzykrotnie
string path = "C:\User\Folder\Plik.txt";
Wraz z pojawieniem się C# 6.0 dostaliśmy możliwość korzystania z poniższego zapisu:
string path = @"C:\User\Folder\Plik.txt";

Kolejnym niesamowitym udogodnieniem było wprowadzenie, również w C# 6.0, znaku interpolacji ciągu: $. Przed pojawiniem się tego znaku używaliśmy poniższego zapisu, który nie zawsze pozostawał czytelny:

static void Main(string[] args)
{
    string brand = "Audi";
    string model = "RS6 C6";
    string engine = "V10";
    string power = "580";

    string sentence = String.Format("Samochód {0} {1} wyposażony w silnik {2} o mocy {3}KM ...", brand, model, engine, power);

    Console.WriteLine(sentence);
    Console.ReadKey();
}
W przypadku dużej ilości parametrów czy skomplikowanych danych związanych z raportami taki zapis mógł utrudniać interpretację całego ciągu. Wraz z pojawieniem się znaku interpolacji zaczeliśmy korzystać z poniższego zapisu (od razu widzimy pasujące parametry):
static void Main(string[] args)
{
    string brand = "Audi";
    string model = "RS6 C6";
    string engine = "V10";
    string power = "580";

    string sentence = $"Samochód {model} {brand} wyposażony w silnik {engine} o mocy {power}KM ...";

    Console.WriteLine(sentence);
    Console.ReadKey();
}

Mam nadzieję, że widzicie do czego zmierzam...

Interpolacja dosłownego wyrażenia

Spróbujmy teraz powiązać dwie powyższe funkcjonalności. Założmy, że mamy dostęp do ścieżki folderu i chcemy przeprowadzić modyfikację wskazanych plików (nie skupiamy się na zaprezentowanym, poglądowym przykładzie, a samej funkcjonalności):

static void Main(string[] args)
{
    string path = String.Empty;
    List<string> files = new List<string>() { "File1.txt", "File2.txt", "File3.txt" };

    foreach (var item in files)
    {
        // Chcemy teraz dwóch funkcjonalności:
        // - interpolacji ciągów;
        // - dosłownej interpretacji ścieżki do pliku
        path = @$"C:/User/Folder{item}";
                
    }
}
Powyższy zapis skutkuje zwróceniem błędu w postaci: Keyword, identifier, or string expected after verbatim specifier: @ - pamiętajcie, że nie jesteśmy jeszcze w świecie C# 8.0.

Problem powyższego zapisu polega na kolejności znaków specjalnych, @ oraz $ powinny zostać odwrócone, aby spełniać kryteria poprawnego zapisu wg. języka. Nie będziemy tego roztrząsać czy zastanawiać się nadmiernie nad interpretacją powyższego zapisu. Poprawny zapis dla języka w wersji od 6 do 7 jest następujący:

path = $@"C:/User/Folder{item}";

C# 8.0 przychodzi z niewielką aktualizacją w której poprawne są oba powyższe zapisy:

path1 = $@"C:/User/Folder{item}";
path2 = @$"C:/User/Folder{item}";

Podsumowanie

Ten krótki wpis mógłby ograniczyć się jedynie do wklejenia powyższego kodu. Wydaje mi się jednak, że kiedy mamy ogólny pogląd na całą sytuację możemy lepiej docenić tę niewielką aktualizację, która pojawiła się w języku C# 8.0. Jeżeli nie było uzasadanienia dla konkretnej kolejności zapisanych znaków – dlaczego nie pozbyć się ograniczenia skoro interpretacja przez kompilator jest dokładnie taka sama? Sam czasem korzystałem z powyższego zapisu i nigdy nie mogłem zapamiętaj poprawnej kolejności – ten problem jest już za nami.

Wpis ten jest początkiem serii kilku artykułów dotyczących nowości, które pojawiały się w języku C# 8.0 - będę skupiał się tradycyjnie na nieco głębszym porównianiu, aby mieć szerszy obraz zmian (i powodów stojących za konkretnymi aktualizacjami).