1 puan yazan GN⁺ 2024-08-09 | 1 yorum | WhatsApp'ta paylaş

Özet

Bu, C# için type union'ları (veya discriminated union'ları) öneren bir belgedir.

Motivasyon

  • Yazılım geliştirirken bir değişkende saklanan değerler her zaman aynı türden olmayabilir.
  • Örneğin müşteri ve tedarikçi tanımları yalnızca bazı özellikleri paylaşıyorsa, bu iki tip üzerinde benzer işlemler yapmak gerekebilir.
  • Bu, kalıtım yoluyla çözülebilir, ancak her durum için uygun değildir.
  • C#'ta sınırlı sayıdaki farklı tipleri aynı değişkende saklayabilmenin bir yoluna ihtiyaç vardır.
  • Diğer diller bu özelliği zaten sunmaktadır.

Çözüm

  • C#'ta union type'ları uygulamanın en uygun yolu, soyut temel sınıf kullanan bir hiyerarşi olarak düşünülebilir.
  • Ancak hiyerarşinin kısıtları ve ilgisiz tiplerin union olarak ifade edilememesi gibi sorunlar vardır.
  • Birden çok union türüne ihtiyaç duyulabilir ve bu öneri bunları dört kategoriye ayırır.

Standart - union class

Bildirim

  • Union class, enum'a benzer şekilde bildirilir.
  • Her üye durum değişkenlerine sahip olabilir.

Oluşturma

  • Üye tiplerin instance'ları atanarak oluşturulur.

Ayrıştırma

  • Type test ve pattern matching ile ayrıştırılır.

Kapsayıcılık

  • Tüm üye tipler switch ifadesi veya deyiminde ele alındığında varsayılan bir case gerekmez.

Null olasılığı

  • Null dahil etmek için standart nullability gösterimi kullanılır.

Uygulama

  • Union class, soyut bir record class olarak uygulanır.

Özelleşmiş - union struct

Bildirim

  • Union class'a benzer şekilde bildirilir, ancak struct anahtar sözcüğü eklenir.

Oluşturma

  • Üye tiplerin instance'ları atanarak oluşturulur.

Ayrıştırma

  • Type test ve pattern matching ile ayrıştırılır.

Kapsayıcılık

  • Tüm üye tipler switch ifadesi veya deyiminde ele alındığında varsayılan bir case gerekmez.

Null olasılığı

  • Null dahil etmek için standart nullability gösterimi kullanılır.

Varsayılan değer

  • Union struct, atanmadığında veya varsayılan değer olarak atandığında tanımsız bir durumda olabilir.

Uygulama

  • Union struct bir struct olarak uygulanır ve üye tipler iç içe record struct'lar olarak uygulanır.

Geçici - ad hoc union

Sözdizimi

  • Ad hoc union, or pattern sözdizimi kullanılarak referans verilir.

Adlandırma

  • Dosya veya global using alias kullanılarak ad hoc union'a ortak bir ad verilebilir.

Oluşturma

  • Üye tiplerin instance'ları atanarak oluşturulur.

Ayrıştırma

  • Type test ve pattern matching ile ayrıştırılır.

Kapsayıcılık

  • Tüm üye tipler switch ifadesi veya deyiminde ele alındığında varsayılan bir case gerekmez.

Null olasılığı

  • Null dahil etmek için standart nullability gösterimi kullanılır.

Karşılıklı değiştirilebilirlik

  • Aynı üye tiplerine sahip ad hoc union'lar birbirinin yerine kullanılabilir.

Kullanıcı tanımlı union

  • Union class veya union struct olarak ifade edilemeyen union tipleri bildirilebilir.
  • Hiyerarşi Closed özniteliği kullanılarak kapatılabilir.
  • Union özniteliği kullanılarak struct wrapper olarak uygulanabilir.

Yaygın union'lar

Option

  • Bir değerin var olabileceği ya da olmayabileceği durumu temsil eden bir struct union'dır.

Result

  • Fonksiyonlardan başarılı sonuç veya hata döndüren bir struct union'dır.

İlgili öneriler

Kapalı hiyerarşi

  • Closed özniteliği kullanılarak soyut temel tip üzerinde kapalı bir alt tip kümesi bildirilir.

Singleton değerler

  • Singleton özniteliğine sahip tipler, tip dışı bağlamlarda değer olarak kullanılabilir.

İç içe üye kısaltması

  • Bağlanmamış adlar kullanılarak hedef tipin statik üyelerine veya iç içe tiplerine bağlanılabilir.

GN⁺ Özeti

  • Bu belge, C# için type union'ları önerir ve çeşitli durumlarda bir değişkende birden fazla tip saklamanın yolunu sunar.
  • Diğer dillerin zaten sunduğu bu özelliği C#'a getirmeyi amaçlayan bir girişimdir.
  • Geliştiricilerin kod okunabilirliğini ve bakım kolaylığını artırmasına yardımcı olabilir.
  • Benzer bir özelliği sunan diğer dillere F# örnek verilebilir.

1 yorum

 
GN⁺ 2024-08-09
Hacker News görüşleri
  • F#'ta ayrımlı union'lar kullanıyordum ve C#'ta da vardır diye düşünmüştüm

    • Java kullanıyorum ve ADT olmayan bir dile geri dönmenin zor olduğunu hissediyorum
    • C#'ın önemli bir özellik eksiğini mazur göstermek zorunda kalmayacak olmaktan memnunum
  • "type union" terimi kulağa yabancı geliyor

    • ML ailesi dillerdeki tagged union'a benziyor gibi görünüyor
    • C# geliştiricilerinin mevcut terimlerden farklı adlar üretme eğilimi olup olmadığını merak ediyorum
  • Uzun yıllardır C# geliştiricisi olarak bu önerinin kullanım alanı bana net gelmiyor

    • Boş bir interface ve record class'lar tanımlayarak bunu gerçekleştirmek mümkün gibi görünüyor
    • Gözden kaçırdığım bir şey olup olmadığını merak ediyorum
  • TypeScript'te type union'lar var

    • F# veya Haskell'deki ayrımlı union'lara benziyor gibi görünüyor
    • Ayrımlı union'larda adlandırılmış case constructor'ları bulunur
  • Pattern matching yapılabilen union'lar olmadan programlama zorlaşıyor

    • Expression problem'in anlamını hiçbir zaman tam olarak kavrayamadım
    • Mevcut polymorphism üzerinden genişleme noktaları sunmak gelecekteki istemciler için uygun olabilir
    • Ekibin sahip olduğu kodlarda pattern matching yapılabilen union'lar daha uygun olur
  • C# union'larında field offset kullanma deneyimim var

    • Pointer/reference değerleri ile değer aliasing'i tanımsız davranışa yol açabilir
    • u64 ile nesnenin struct union'ı ayrı alanlar gerektirdiği için 8 byte israf edebilir
  • Özel constructor'lar ve bir nuget paketi kullanarak switch type'ın _ case'ine ihtiyaç duymamasını sağlıyorum

    • Bu, önerilen "union class"ın desugared sürümüne benziyor
    • nuget paketine artık ihtiyaç kalmaması ve sözdizimsel şeker eklenmesi güzel olur
  • Union struct'ların eşzamanlı değişikliklerde tearing'i nasıl ele aldığı belirtilmiyor

    • Tearing, bellek güvenliği sorunlarına yol açabilir
    • Aynı offset'te integer field ve reference field içeren varyantlar olabilir