• Per. Ara 26th, 2024

Arif GÖKÇE

Senior Software Engineer

C# ile Smart Enum Kullanımı

Byarifgokce

Haz 21, 2023

Smart Enum kullanımı, C# kullanarak kullanabileceğiniz bir özellik olan Smart Enums (Akıllı Numaralandırmalar), kodunuzu daha okunaklı ve anlaşılır hale getirmenize yardımcı olabilir. Geleneksel olarak, bir enum tipi yalnızca sabit değerler içeren bir veri tipidir. Ancak Smart Enums, enum tipine ek işlevsellikler ekler. Örneğin, bir dize değerini bir enum değerine eşleştirmek için kullanılan Parse yöntemini sağlayabilir.

Bu, kodunuzda enum sabitini belirli bir enum sabiti kullanmak yerine bir dize olarak belirtmenizi sağlar. Ayrıca, Smart Enumlar, enum sabitlerine özel davranışlar eklemek için kullanılabilir. Örneğin, bir enum sabiti için belirli fonksiyonlar tanımlayabilir. Bu, kodunuzu daha okunaklı ve anlaşılır hale getirmenize yardımcı olabilir. Aşağıda bir Smart Enum C# kodu örneği verilmiştir:

//SmartEnum sınıfı
public abstract class SmartEnum<TEnum, TValue> where TEnum : SmartEnum<TEnum, TValue>
{
// ConcurrentDictionary, çoklu iş parçacıklı uygulamalarda eş zamanlı kullanım için tasarlanmış bir koleksiyon sınıfıdır.
private static readonly ConcurrentDictionary<TValue, TEnum> _items =
new ConcurrentDictionary<TValue, TEnum>();

// SmartEnum sınıfının her örneği bir değer (Value) ve bir isim (Name) taşır.
public TValue Value { get; }
public string Name { get; }

// SmartEnum sınıfı, örneklendiğinde değer ve isim bilgileri verilir.
protected SmartEnum(TValue value, string name)
{
Value = value;
Name = name;
}

static SmartEnum()
{
// Tüm enum değerleri otomatik olarak kaydedilir.
foreach (var field in typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static))
{
var item = (TEnum)field.GetValue(null);
Register(item);
}
}

// Bir değere göre enum değeri getirilir.
public static TEnum FromValue(TValue value)
{
return _items[value];
}

// Bir değere göre enum değeri getirilir. İşlem başarılı ise true değeri döndürülür.
public static bool TryFromValue(TValue value, out TEnum result)
{
return _items.TryGetValue(value, out result);
}

// Tüm enum değerleri bir koleksiyonda toplanarak döndürülür.
public static IEnumerable<TEnum> GetAll()
{
return _items.Values;
}

// Enum değeri kaydedilir.
protected static TEnum Register(TEnum item)
{
return _items.GetOrAdd(item.Value, item);
}

// Enum değerinin adı döndürülür.
public override string ToString()
{
return Name;
}
}

//--------------------------------------------------------------
// SmartEnum sınıfından kalıtım alan Gender sınıfı.
public class Gender : SmartEnum<Gender, string>
{
// Gender sınıfının tüm sabit değerleri örneklenir.
public static readonly Gender Male = new Gender("M", "Male");
public static readonly Gender Female = new Gender("F", "Female");
public static readonly Gender Unknown = new Gender("U", "Unknown");

// Gender sınıfı, örneklendiğinde değer ve isim bilgileri verilir.
public Gender(string value, string name)
: base(value, name)
{
}
}

//--------------------------------------------------------------
// Program.cs
using SmartEnums;

Gender gender = Gender.FromValue("M");
if (gender == Gender.Male)
{
Console.WriteLine("Çalışan bir erkek");
}

Console.ReadLine();

Smart Enumların Klasik Enumlarla Karşılaştırılması

Bu örnekte, Smart Enum sınıfı Smart enum temelini oluşturur. Bu sınıf, Smart enumlar Value ve Name özelliklerini tanımlar. Register yöntemi smart enumlar için kayıt işlemini gerçekleştirir. FromValue yöntemi bir değer alır ve karşılık gelen smart enumlar sabitini döndürür. TryFromValue yöntemi FromValue ile aynı işlemi yapar, ancak bir değerin bir smart enum olarak varlığını da kontrol eder. Bu SmartEnum sınıfı, smart enumların uygulanması için temel işlevselliği sağlar. Bu yöntemleri anlayarak ve kullanarak, geliştiriciler daha okunaklı ve bakımı kolay kodlar oluşturabilirler.

Klasik enumlar ile smart enumların karşılaştırılması Bu bölümde, örnekler, avantajları ve dezavantajları tartışılarak, smart enumlar ile klasik enumlar ile karşılaştırılacak. Başlayalım!

Valuekerin kolay yönetimi(Easy management of values:): Smart enumlar, enum sabitlerini daha özelleştirilebilir hale getirerek, özellikler ve fonksiyonlar ekleyebilir. Bu, enum sabitleri arasındaki farkı daha net bir şekilde ortaya koyar ve hataları önler.

public enum Gender
{
    Male,
    Female,
    Unknown
}

//Smart Enum
public class Gender : SmartEnum<Gender, string>
{
    public static readonly Gender Male = new Gender("M", "Male");
    public static readonly Gender Female = new Gender("F", "Female");
    public static readonly Gender Unknown = new Gender("U", "Unknown");

    private Gender(string value, string name)
        : base(value, name)
    {
    }
}

Okunabilirlik(Readability): Smart enumlar, enum sabitlerini daha anlaşılır ve okunaklı hale getirir. Sabitlerin anlamı daha net ve kod daha anlaşılır hale gelir.

public enum UserRole
{
    Admin,
    Manager,
    Employee
}

//Smart 
public class UserRole : SmartEnum<UserRole, int>
{
    public static readonly UserRole Admin = new UserRole(1, "Admin");
    public static readonly UserRole Manager = new UserRole(2, "Manager");
    public static readonly UserRole Employee = new UserRole(3, "Employee");

    private UserRole(int value, string name)
        : base(value, name)
    {
    }

Esneklik(Flexibility): Smart enumlar, enum sabitlerine özellikler ve fonksiyonlar ekleyerek daha esnek bir yapı oluşturabilir. Bu, kodun daha modüler hale gelmesini ve kodun yeniden kullanılabilirliğinin artmasını sağlar.

public enum PaymentType
{
    CreditCard,
    DebitCard,
    BankTransfer
}

//Smart
public sealed class PaymentType : SmartEnum<PaymentType, string>
{
    public static readonly PaymentType CreditCard = new PaymentType("CC", "Credit Card", new CreditCardPaymentProcessor());
    public static readonly PaymentType DebitCard = new PaymentType("DC", "Debit Card", new DebitCardPaymentProcessor());
    public static readonly PaymentType BankTransfer = new PaymentType("BT", "Bank Transfer", new BankTransferPaymentProcessor());

    private PaymentType(string value, string name, IPaymentProcessor paymentProcessor)
        : base(value, name)
    {
    }

}

Esneklik(Flexible Values): Smart enumlar, enum sabitlerine özellikler ve fonksiyonlar ekleyerek daha esnek bir yapı oluşturabilir. Bu, kodun daha modüler hale gelmesini ve kodun yeniden kullanılabilirliğinin artmasını sağlar.

public sealed class Colors : SmartEnum<Colors, string>
{
    public static readonly Colors Red = new Colors("R", "Red");
    public static readonly Colors Green = new Colors("G", "Green");
    public static readonly Colors Blue = new Colors("B", "Blue");

    private Colors(string value, string name)
        : base(value, name)
    {
    }
}

Sabitleri Gruplama (Grouping Constants): Smart Enums, sabitleri gruplamanıza olanak tanır. Bu, kodun daha okunaklı ve anlaşılır hale gelmesini sağlar.

// Classic
public enum PizzaType
    {
        MeatLovers,
        Vegetarian,
        PineappleLovers
    }

//Smart 
public sealed class Pizza : SmartEnum<Pizza>
{
    public static readonly Pizza Margherita = new Pizza(1, "Margherita", PizzaType.Vegetarian);
    public static readonly Pizza Pepperoni = new Pizza(2, "Pepperoni", PizzaType.MeatLovers);
    public static readonly Pizza Hawaiian = new Pizza(3, "Hawaiian", PizzaType.PineappleLovers);
    public static readonly Pizza MeatLovers = new Pizza(4, "Meat Lovers", PizzaType.MeatLovers);
    public static readonly Pizza VeggieLovers = new Pizza(5, "Veggie Lovers", PizzaType.Vegetarian);

    public int Id { get; }
    public string Name { get; }
    public PizzaType Type { get; }

    private Pizza(int id, string name, PizzaType type)
    {
        this.Id = id;
        this.Name = name;
        this.Type = type;
    }
}

Nesne Oluşturma(Object Creation): Smart enumlar, sabitlerinizi nesnelere eşleyerek kullanmanıza olanak tanır. Bu, sabitlerinizin özelliklere, yöntemlere ve davranışlara sahip olmasına olanak verir.

public sealed class Pizza : SmartEnum<Pizza>
{
    public static readonly Pizza Margherita = new Pizza(1, "Margherita", 10m);
    public static readonly Pizza Pepperoni = new Pizza(2, "Pepperoni", 12m);
    public static readonly Pizza Hawaiian = new Pizza(3, "Hawaiian", 15m);

    public int Id { get; }
    public string Name { get; }
    public decimal Price { get; }

    private Pizza(int id, string name, decimal price)
    {
        this.Id = id;
        this.Name = name;
        this.Price = price;
    }

    public void PrintDescription()
    {
        Console.WriteLine($"{this.Name} pizza is {this.Price:C}.");
    }
}

Özetleyecek olursam, bu Enum kullanmanın avantajları şunlardır:

Geliştirilmiş kod okunabilirliği. smart enumlar, klasik enumlardan daha anlamlı ve okunaklı olabilir. enum sabitleri için özel özellikler ve davranışlar tanımlayabiliriz. enum sabitlerini nesneler olarak ele alabilir, kodumuzu daha esnek hale getirebiliriz. Klasik enumlarda ortaya çıkan güvenlik ve tutarlılık sorunları ortadan kalkar. Smart enumlar kullanarak, geliştiriciler okunması, bakımı ve anlaşılması daha kolay olan kod oluşturabilirler. Ayrıca, smart enumlar ek esneklik ve özelleştirilebilirlik sağlar, bu da herhangi bir geliştirme projesinde değerli bir araç yapar. Smart enumlar ayrıca aşağıdaki durumlarda özellikle faydalıdır:

Enum sabitleri, özellikleri ve davranışlarıyla birlikte kullanılacak. Sabit değerleri çalışma zamanında hesaplanır veya dinamik olarak belirlenir. Sabitlerin doğruluğunu ve tutarlılığını garanti etmek istiyoruz. Tüm bu avantajların yanı sıra herhangi bir dezavantaj var mı diye sorarsanız, elbette vardır. Bunlar aşağıdaki gibidir:

Sınırlı destek(Limited support): C# dili dışında doğrudan desteklenmeyen bir özellik olarak kabul edilir. Bu nedenle, C# dışındaki diğer dillerde kullanılabilirliği sınırlıdır.

Öğrenme eğrisi(Learning curve): Klasik enumların aksine, smart enumlar öğrenme eğrisi gerektirir. Bu, öğrenme sürecini yeni başlayanlar için biraz daha zor hale getirebilir.

Performans(Performance): Smart enumlar biraz daha fazla hesaplama ve bellek kullanımı gerektirebilir. Bu, uygulamaların performansını etkileyebilir.

Bu makalemin sonuna geldim. Bu yazımda enumları inceledik ve anlattık. Okuduğunuz için teşekkür ederim başka bir makalede görüşmek üzere.

Arif GÖKÇE