Kolejny trochę mniej spóźniony wpis o nowościach w C# 7.1. Kolejne wersje języka wychodzą tak często, że bez częstego przypominania sobie o nowościach możemy łatwo je pominąć w codziennej pracy. Zapraszam na opis i analizę nowości w C# 7.1.
Nowości z C# 7.0, gdyby ktoś chciał sobie przypomnieć są tutaj.
Spis treści
Asynchroniczna metoda Main
Jeśli chcieliśmy testować metody async/await w aplikacji konsolowej to zawsze był problem z tym, że musimy stworzyć osobny wątek do tego by w nim wywoływać metody asynchroniczne. Od C# 7.1 możemy zamienić metodę Main na asynchroniczną wersję i dzięki temu uzyskać punkt wejścia do metod asynchronicznych.
static async Task Main() { await SomeAsyncMethod(); }
lub taką, którą zwraca tzw: exit code (int)
static async Task<int> Main() { return await DoAsyncWork(); }
Doroba przyjemna zmiana, chyba głównie pod testowanie metod asynchronicznych.
Uproszczenie stosowania słowa kluczowego default
Słowo kluczowe default używamy aby wydobyć w łatwy sposób domyślną wartość dla typu. Dla typów referencyjnych to null a dla typów wartościowych to zależy. Najczęściej używa się tej instrukcji, gdy piszemy generyczną metodę (default(T)). Gdy nie znamy typu a chcemy mieć domyślna wartość Domyślna składnia to:
private void DefaultFeature() { int number = default(int); // 0 Point point = default(Point); // struct - point.X = 0 point.Y = 0 }
Dzięki zmianom teraz można uprościć zapis na taki:
private void DefaultFeature() { int number = default; // 0 Point point = default; // struct - point.X = 0 point.Y = 0 }
lub dla typów generycznych
private void DefaultFeature<T>(T unknownType) { T defaultUnknownValue = default; }
Kompilator sam domyśli się typu dla instrukcji default i ustawi go jako jak obowiązujący typ. Kosmetyczna zmiana, intuicyjna i wygodna.
Domyśle nazwy dla Tupli
Kolejna wersja języka i kolejne ulepszenie dla Tupli. W C# 7.0 można było w łatwy sposób stworzyć Tuple z nazwanymi parametrami w ten sposób:
private void TupleWithName() { // C# 7.0 int number = 1983; var name = "Przemek"; var tuple = (Name: name, Number: number); Console.WriteLine(tuple.Name); // Przemek Console.WriteLine(tuple.Number); // 1983 }
Nie wygodne było to, że musimy ręcznie wypisywać nazwy pól. Dzięki C# 7.1 możemy polegać na kompilatorze, który stworzy domyślne nazwy z nazw zmiennych przekazanych do Tupli. Poniżej przykład:
private void TupleWithName() { // C# 7.1 int Number = 1983; var Name = "Przemek"; var tuple = (Name, Number); Console.WriteLine(tuple.Name); // Przemek Console.WriteLine(tuple.Number); // 1983 }
Zmiana bardzo dobra ale widzę wyraźny minus.
Nazwy są brane bezpośrednio z nazw zmiennych. Gdy zmienna zaczyna się od małych liter, to pola są od małych liter. Nie zawsze jest to zgodne z konwencją nazewnictwa, może to powodować pogorszenie jakości kodu.
Podsumowanie
Zmiany w C# 7.1 były nie wielkie i mam wrażenie, że próbują skrócić coś co już i tak jest dość krótkie. Czy to dobrze? Uważam, że nie za bardzo. „Wszystko powinno być tak proste, jak to tylko możliwe, ale nie prostsze” – Einstein. Wydaje mi, te zmiany idą właśnie w tym kierunku.