C# 8

Paylaş

C# 8 ile birlikte gelen Readonly Instance Members, Default interface methods, Switch expressions, Nullable reference types, Using declarations gibi yenilikler C# kod örnekleri ile birlikte yer alıyor.

C# 8 ile gelen özelliklere bakmadan önce C# 7, 7.1, 7.2 ve 7.3 ile gelen özelliklere buradan bakabilirsiniz.

Readonly Instance Members

Özellik C# 7.2 ile gelen readonly structs özelliğini genişleterek sadece struct members için readonly anahtar kelimesini kullanımayı sağlar.

using System;

struct Person {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public readonly string FullName => $"{FirstName} {LastName}";

    public readonly override string ToString() {
        return $"{Id} {FirstName} {LastName} -> {FullName}"; // FullName readonly olmalı
    }

}

class Program {
    public static void Main(string[] args) {
        Person yusuf = new Person { Id = 1, FirstName = "Yusuf", LastName = "Sezer" };
        // İzin verilmez
        // Person sefa = new Person { Id = 2, FirstName = "Sefa", LastName = "Sezer", FullName= };
        Console.WriteLine(yusuf);
    }
}

Örnekte FullName readonly belirtilmediğinde ToString metodu örtük kopya uyarısı verecektir.

Özellik sadece okunabilir özellik ve metotlarda kullanımı performansı arttırmaktadır.

Default interface methods

Özellik interface içerisinde içeriği olan varsayılan metot tanımlamayı sağlar.

interface IMyDate {
    void SetDate(int month, int year, int day);
    int getYear();
    int getMonth();
    int getDay();
    DateTime GetDate() {
        return new DateTime(getYear(), getMonth(), getDay());
    }
}

Özellik NYP prensip ve desenlerini değiştirmesine rağmen önceden tanımlı arayüzlere metot eklemede fayda sağlamaktadır.

Recursive Pattern Matching

C# 7 ile birlikte gelen Pattern matching özelliğini kullanımı Switch expressions, Property patterns, Tuple patterns ve Positional pattern ile genişletilmiştir.

using System;

class Program {
    public static void Main(string[] args) {
        DayOfWeek dayOfWeek = GetDay(3);
        // Property patterns
        bool isBirthday = DateTime.Now is { Year: 2023, Month: 1, Day: 1 };

        // Tuple patterns
        switch (dayOfWeek, isBirthday) {
            case (DayOfWeek.Thursday, true):
                Console.WriteLine("Doğum günü");
                break;
            case (DayOfWeek.Sunday, false):
                Console.WriteLine("Tatil günü");
                break;
            default:
                Console.WriteLine("Çalışma günü");
                break;
        }

        var gun = (dayOfWeek, isBirthday);

        // Positional patterns
        string gunStr = gun switch {
            (DayOfWeek.Thursday, true) => "Doğum günü",
            (DayOfWeek.Sunday, false) => "Tatil günü",
            _ => "Çalışma günü"
        };
        Console.WriteLine(gunStr);
    }

    // Switch expressions
    public static DayOfWeek GetDay(int day) => day switch {
        1 => DayOfWeek.Monday,
        2 => DayOfWeek.Tuesday,
        3 => DayOfWeek.Wednesday,
        4 => DayOfWeek.Thursday,
        5 => DayOfWeek.Friday,
        6 => DayOfWeek.Saturday,
        7 => DayOfWeek.Sunday,
        _ => throw new ArgumentOutOfRangeException()
    };
}

Using declarations

Özellik using ifadesini kullanımı süslü parantez kullanmadan daha sade hale getirmektedir.

using System.IO;

class Program {
    public static void Main(string[] args) {
        // C# 8 öncesi
        using (StreamWriter streamWriter1 = File.CreateText("metin.txt")) {
            streamWriter1.WriteLine("Yusuf Sezer");
        }

        // C# 8 sonrası
        using StreamWriter streamWriter2 = File.CreateText("metin.txt");
        streamWriter2.WriteLine("Yusuf Sezer");
    }
}

Özelliği kullanımı için gerekli olan IDisposable arayüzü hakkında bilgi almak için C# IDisposable Nedir? Kullanımı yazıma bakmalısın.

Static local functions

Özellik C# 7 ile birlikte gelen local functions özelliğinden farklı olarak değişkenlere erişim sağlayamaz.

using System;

class Program {
    public static void Main(string[] args) {
        int sayi1 = 10;
        int sayi2 = 20;
        Yazdir1();

        // Local functions
        void Yazdir1() {
            Console.WriteLine($"{sayi1} {sayi2} {sayi1 + sayi2}");
        }

        // Static Local functions
        static void Yazdir2() {
            //Console.WriteLine($"{sayi1} {sayi2} {sayi1 + sayi2}"); // Değişkenlere erişemez.
        }
    }
}

Disposable ref structs

Özellik C# 7.2 ile birlikte gelen ref structs özelliğine IDisposable arayüzünü kullanmadan using anahtar kelimesini kullanarak bellek yönetimi yapmayı sağlar.

using System;

ref struct Person{
    public void Dispose() => Console.WriteLine("Silindi");
}

class Program {
    public static void Main(string[] args) {
        using var yusuf = new Person();
    }
}

Nullable reference types

Özellik referans türünden değerlerin null değer alabileğini açıkca ifade etmek için ? operatörünü kullanmaya zorlar.

class Person {
    public Guid Id { get; } = Guid.NewGuid();
    public string? FirstName { get; set; } // Nullable reference types
    public string? LastName { get; set; } // Nullable reference types
}

Özelliğin kullanılabilmesi için .csproj dosyasına <Nullable>enable</Nullable> eklenmesi veya #nullable enable ile #nullable disable ön derleme ifadelerin kullanılması yeterli olacaktır.

Nullable reference types özelliği maliyetli NullReferenceException istisnasını en aza indirmeyi amaçlar.

Asynchronous streams

Özellik koleksiyon veya enumerator ile çalışan foreach, while yapılarını asenkron olarak kullanmayı IAsyncEnumerable, IAsyncEnumerator ve IAsyncDisposable ile sağlar.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program {
    public static async Task Main(string[] args) {
        await foreach (var number in GenerateNumbersAsync()) {
            Console.WriteLine(number);
        }
    }

    public static async IAsyncEnumerable<int> GenerateNumbersAsync() {
        for (int i = 0; i < 10; i++) {
            await Task.Delay(100); // asenkron uzun bir işlem
            yield return i; // sonuç döndürülür
        }
    }
}

Indices and ranges

Özellik dizi elemanlarına daha kolay ve etkili erişmek için System.Index ve ^ (şapka operatörü) ile System.Range ve […] (aralık operatörü) ile sağlar.

using System;

class Program {
    public static void Main(string[] args) {
        // Indices - System.Index ve ^ operatörü
        string[] names = { "Yusuf", "Sefa", "Sezer" };
        Console.WriteLine($"{names[0]} {names[^1]}");

        // Ranges - System.Range
        string[] secondName = names[1..]; // Range.StartAt(2)
        string[] allName = names[..]; // Range.All
        Console.WriteLine(string.Join('-', secondName));
        Console.WriteLine(string.Join('-', allName));
    }
}

Null-coalescing assignment

Özellik C# 6 ile birlikte gelen Null propagator özelliğini genişleterek null ise atama yapmayı ??= operatörü ile sağlar.

using System;
using System.Collections.Generic;

class Program {
    public static void Main(string[] args) {
        List<string> names = null;
        names ??= new List<string>() { "Yusuf", "Sezer" }; // Null-coalescing Assignment
        Console.WriteLine(string.Join(' ', names));
    }
}

C# 6 ile gelen özelliklere bakmak için C# 6 yazıma bakmalısın.

Unmanaged constructed types

Özellik yönetilmeyen türlerin generic programlama yönteminde kullanımını genişletmiştir.

using System;

struct Nokta<T> {
    public T X { get; set; }
    public T Y { get; set; }
}

class Program {
    public static void Main(string[] args) {
        Span<Nokta<float>> noktalar = stackalloc[] {
            new Nokta<float> { X = 34F, Y = 55F },
            new Nokta<float> { X = 55F, Y = 72F }
        };
        foreach (var nokta in noktalar) {
            Console.WriteLine($"X: {nokta.X} Y: {nokta.Y}");
        }
    }
}

Özellik sayesinde struct veya yapılarda generic programlama kullanılarak stackalloc ile ifade edilmiştir.

Stackalloc in nested expressions

Özellik Span, ReadOnly türündeki parametre yerine stackalloc ifadesini kullanmayı sağlar.

using System;

class Program {
    public static void Main(string[] args) {
        Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 };
        var index = numbers.IndexOfAny(stackalloc[] { 4, 8, 12 });
        Console.WriteLine(index);
    }
}

interpolated verbatim strings

C# 6 ile birlikte gelen String interpolation $”Merhaba {name}” ile vertabim string @”” birlikte $@ veya @$ olarak kullanmayı sağlar.

using System;

class Program {
    public static void Main(string[] args) {
        string name = "Yusuf Sezer";
        string mesaj = $@"Merhaba sayın {name}
uzun bir mesaj
görüşmek üzere";
        Console.WriteLine(mesaj);
    }
}

Özellikle birlikte uzun metin içerisinde değişken kullanmaya imkan sağlar.

C# 8 önceki C# sürümlerinde özellik kullanımın genişletilmesi, belleğe doğrudan erişiminde kullanılan yönetilemeyen kod desteği arttırılarak performanslı uygulamalar için alt yapı hazırlamıştır.

Bunun yanında default interface methods gibi özelliklerle NYP temelleri değişikliğe uğramıştır.

C# 8 sürümünü kullanmak için .csproj dosyasında <LangVersion>8.0</LangVersion> ifadesini kullanımı yeterli olacaktır.

Yeni gelen özellikleri .NET Core 2.1 ve roslyn derleyicisi ile kullanabilirsiniz.

.NET Derslerine buradan ulaşabilirsiniz.

Hayırlı günler dilerim.


Bunlarda ilgini çekebilir


LinkedIn grubuna buradan katılın.