19 Mayıs 2019 Pazar

Operator == Overloading

Giriş
Bu tür kodları hiç sevmiyorum. Dili ve kodu çok karmaşık hale getiriyor.

operator == ve NullReferenceException
Yazılan kodlarda gelen parametrelerin null olabileceğine dikkat etmek gerekir.
Örnek
Elimizde şöyle bir kod olsunn
class Test
{
  public string SomeProp { get; set; }
    
  public static bool operator ==(Test test1, Test test2)
  {
    return test1.SomeProp == test2.SomeProp;
  }
  public static bool operator !=(Test test1, Test test2)
  {
    return !(test1 == test2);
  }
}
Şöyle çağıralım. NullReferenceException alırız
Test test1 = null;
bool x = test1 == null;

Örnek
Thing isimli sınıfımız ve içinde bir Id alanı olsun. Sınıfın için operator == ve operator != metodunu eklemek için şöyle yaparız.
public static bool operator ==(Thing self, Thing other)
{
  return !ReferenceEquals(self, null) && 
         !ReferenceEquals(other, null) && 
         self.Id == other.Id;
}

public static bool operator !=(Thing self, Thing other)
{
  return !(self == other);
}
Örnek
Şöyle yaparız.
using System;

class Test
{
  // All this code is awful. PURELY FOR DEMONSTRATION PURPOSES.
  public static bool operator==(Test lhs, Test rhs) => true;
  public static bool operator!=(Test lhs, Test rhs) => true;        
  public override bool Equals(object other) => true;
  public override int GetHashCode() => 0;

  static void Main()
  {
    Test a = null;
    Test b = null;
    Console.WriteLine(a != b);    // True
    Console.WriteLine(!(a == b)); // False
  }    
}
Örnek
operator == için kısıt verebiliriz. T için SillyClass kısıtı vermek için şöyle yaparız.
class SillyClass
{
    public static string operator ==(SillyClass x, SillyClass y) => "equal";
    public static string operator !=(SillyClass x, SillyClass y) => "not equal";
}

class SillySubclass : SillyClass
{
    public static string operator ==(SillySubclass x, SillySubclass y) => "sillier";
    public static string operator !=(SillySubclass x, SillySubclass y) => "very silly";
}

var x = new SillySubclass();
var y = new SillySubclass();
OpTest(x, y);


static void OpTest<T>(T x, T y) where T : SillyClass
{
  Console.WriteLine(x == y);
  Console.WriteLine(x != y);
}
Çıktı olarak "equal, not equal" alırız

String Sınıfı
String için operator == overload edilmiştir ve reference comparison yerine denklik karşılaştırması yapar. Şöyle yaparız.
string x = "test";
string y = new string(x.ToCharArray());
Console.WriteLine(x == y); // Use string overload, checks for equality, result = true
Console.WriteLine(x.Equals(y)); // Use overridden Equals method, result = true
Console.WriteLine(ReferenceEquals(x, y)); // False because they're different objects
Console.WriteLine((object) x == (object) y); // Reference comparison again- result = false


Hiç yorum yok:

Yorum Gönder