6 Şubat 2020 Perşembe

Operatörlere Aşırı Yükleme (implicit - explicit)

    S.A. Arkadaşlar,
    Bugün operatörlere aşırı yükleme işlemine göz atacağız. Metodlara aşırı yükleme ile benzer mantıkta olsa da farklı işlemlerdir. Genel kullanımı +, - gibi operatörlere aşırı yükleme yapılır. Normal koşullarda 2 nesne toplanamaz, fakat biz operatörlere aşırı yükleme yaparak artık bu operatörleri istediğimiz gibi kullanabiliyoruz. Burada implicit and explicit diye 2 tür dönüştürme vardır. Implicit aritmetik işlemleri içerir ve veri kaybı olmadığından cast işlemi de gerektirmez. Explicit ise cast işlemi gerektirir, veri kaybı olma ihtimali de vardır.

      Bu yazıyı yazmamın belki de en önemli sebebi rastladığım kaynak veya yazıların bir çoğunun aritmetik işlemler yapması ve tam olarak gerçek projede kullanımı konusunda beni tatmin etmemesidir. O yüzden microsoft'un kendi sitesinden aldığım aritmetik yükleme ile ilgili olan kodu paylaşmak istiyorum. Daha sonra yazıyı yazmama vesile olan kısma geçeceğim.
using System;

public readonly struct Digit
{
    private readonly byte digit;

    public Digit(byte digit)
    {
        if (digit > 9)
        {
            throw new ArgumentOutOfRangeException(nameof(digit), "Cannot be greater than nine.");
        }
        this.digit = digit;
    }

    public static implicit operator byte(Digit d) => d.digit;
    public static explicit operator Digit(byte b) => new Digit(b);

    public override string ToString() => $"{digit}";
}

public static class UserDefinedConversions
{
    public static void Main()
    {
        var d = new Digit(7);
        
        byte number = d;
        Console.WriteLine(number);  // output: 7

        Digit digit = (Digit)number;
        Console.WriteLine(digit);  // output: 7
    }
}

    Burada belirtmek istediğim şey implicit ile operatörü aşırı yüklediğimizde her hangi bir cast işlemi uygulamadık, fakat explicit ile durum farklı olup cast işlemi kullandık.

     Şimdi ise iki tip nesnemiz olsun: UserAccount ve UserAccountDto. UserAccount içerisinde kalabalık property değişkenlerimiz mevcut fakat UserAccountDto içerisinde hepsini kullanmak istemiyoruz. Çünkü tüm property'lere ihtiyacımız olmayacak. Hem güvenlik hem veri boyutu vb birden çok sebepleri var. Bunu yapmanın tabi ki birden çok yolu olabilir, ama biz burada bu yöntemi kullanacağız.
public class UserAccount
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string EMail { get; set; }
    public string Others { get; set; }

    public static explicit operator UserAccountDto(UserAccount userAccount)
    {
        return new UserAccountDto()
        {
            Id = userAccount.Id,
            Name = userAccount.Name,
            EMail = userAccount.EMail

        };
    }

    public static implicit operator UserAccount(UserAccountDto dto)
    {
        using (var context = new YourDatabaseContext())
        {
            return context.User.Where(ua => ua.Id == dto.Id).SingleOrDefault();
        }
    }
}
public class UserAccountDto
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string EMail { get; set; }
}

     Burada önemli olan bir nokta ise yaptığımız aşırı yüklemelerin iki nesnenin birinde tanımlanması  gerekmektedir, yoksa hata alırsınız. Temel olarak iki nesne arasında dönüşüm işlemi mevcuttur. Birincisinde elimizdeki UserAccountDto => UserAccount işlemi yaparken, ikinci kısımda ise veri tabanından çektiğimiz nesneyi dto'ya çevirmektedir (UserAccount => UserAccountDto).

      Şimdi ise oluşturduğumuz yapıyı kullanma vakti geldi.
public class RunCode
 {
     public RunCode()
     {
         var useraccount = new UserAccount()
         {
             Id = 1903,
             Name = "Malik",
             EMail = "malik.masis@gmail.com",
             Others = "Others"
         };

         UserAccountDto userAccountDto = (UserAccountDto)useraccount;
     }

     public RunCode(UserAccountDto userAccountDto)
     {
         UserAccount userAccount = userAccountDto;
     }
 }

    Birinci kısımda elimizdeki UserAccount nesnesini dto'ya çevirdik. Tüm verileri değil sadece ihtiyaç duyduğumuz property'leri elde ediyoruz. İkinci kısımda ise elimizdeki dto nesnesi ile (metoda id verisi dolu geldiğini kabul ediyoruz ve o da veri tabanından ilgili kaydı getirmektedir) userAccount nesnesini getirebiliyoruz.

    Yazının başında belirttiğim gibi operatörlere aşırı yüklemenin her iki şekli de mevcut, fakat benim odaklanmak istediğim yer ikinci kısımdı. Asıl eksikliğin burada olduğunu düşündüğüm için buraya odaklanma ihtiyacı hissettim. Yine belirttiğim gibi bunu yapmanın birden farklı yolu mevcuttur. Bunlardan biri de mapleme yöntemidir, bir de bu şekilde yapıldığını belirtmek istedim.

    Yazıyı yazmama vesile olan arkadaşım ve genç olmasına rağmen kendisinden çok şey öğrendiğim Ahmet'e de teşekkür ederim. Ayrıca konunun detaylarına dair bir yazı da paylaşmak isterim.

     Kullandığımız programlama dilini derinlemesine öğrenmek dileğiyle.

Hiç yorum yok:

Yorum Gönder