Nowości w C# 7.1

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.