Aracılığıyla paylaş


İşleç aşırı yüklemesi - önceden tanımlanmış tekli, aritmetik, eşitlik ve karşılaştırma işleçleri

Kullanıcı tanımlı bir türde önceden tanımlanmış bir C# işlecini aşırı yükleyebilirsiniz. Bir işleci aşırı yükleyerek, işlenenlerden biri veya her ikisi de bu tür olduğunda işlem için özel bir uygulama sağlarsınız. Aşırı yükleyebileceğiniz C# işleçlerinin listesi için Aşırı Yüklenebilir işleçler bölümüne bakın.

C# dili başvuru belgesi, C# dilinin en son yayımlanan sürümünü gösterir. Ayrıca, yaklaşan dil sürümü için genel önizlemelerdeki özelliklere yönelik ilk belgeleri içerir.

Belgelerde ilk olarak dilin son üç sürümünde veya geçerli genel önizlemelerde sunulan tüm özellikler tanımlanır.

Tavsiye

Bir özelliğin C# dilinde ilk tanıtıldığı zamanları bulmak için C# dil sürümü geçmişi makalesine bakın.

operator bir işleci bildirmek için anahtar sözcüğünü kullanın. Bir işleç bildirimi aşağıdaki kuralları karşılamalıdır:

  • Bir değiştirici içerir public .
  • Birli işleç bir giriş parametresine sahiptir. İkili işleç iki giriş parametresine sahiptir. Her durumda, en az bir parametrenin türü T olmalıdır veya T? burada T işleç bildirimini içeren türdür.
  • static değiştiriciyi, += gibi bileşik atama işleçleri dışında içerir.
  • Artım (++) ve azaltma (--) işleçleri statik veya örnek yöntemleri olarak uygulanabilir. Örnek yöntemi işleçleri, C# 14'te kullanıma sunulan yeni bir özelliktir.

Aşağıdaki örnek, rasyonel bir sayıyı temsil eden basitleştirilmiş bir yapı tanımlar. Yapı, bazı aritmetik işleçleri aşırı yükler:

public struct Fraction
{
    private int numerator;
    private int denominator;

    public Fraction(int numerator, int denominator)
    {
        if (denominator == 0)
        {
            throw new ArgumentException("Denominator cannot be zero.", nameof(denominator));
        }
        this.numerator = numerator;
        this.denominator = denominator;
    }

    public static Fraction operator +(Fraction operand) => operand;
    public static Fraction operator -(Fraction operand) => new Fraction(-operand.numerator, operand.denominator);

    public static Fraction operator +(Fraction left, Fraction right)
        => new Fraction(left.numerator * right.denominator + right.numerator * left.denominator, left.denominator * right.denominator);

    public static Fraction operator -(Fraction left, Fraction right)
        => left + (-right);

    public static Fraction operator *(Fraction left, Fraction right)
        => new Fraction(left.numerator * right.numerator, left.denominator * right.denominator);

    public static Fraction operator /(Fraction left, Fraction right)
    {
        if (right.numerator == 0)
        {
            throw new DivideByZeroException();
        }
        return new Fraction(left.numerator * right.denominator, left.denominator * right.numerator);
    }

    // Define increment and decrement to add 1/den, rather than 1/1.
    public static Fraction operator ++(Fraction operand)
        => new Fraction(operand.numerator + 1, operand.denominator);

    public static Fraction operator --(Fraction operand) =>
        new Fraction(operand.numerator - 1, operand.denominator);

    public override string ToString() => $"{numerator} / {denominator}";

    // New operators allowed in C# 14:
    public void operator +=(Fraction operand) =>
        (numerator, denominator ) =
        (
            numerator * operand.denominator + operand.numerator * denominator,
            denominator * operand.denominator
        );

    public void operator -=(Fraction operand) =>
        (numerator, denominator) =
        (
            numerator * operand.denominator - operand.numerator * denominator,
            denominator * operand.denominator
        );

    public void operator *=(Fraction operand) =>
        (numerator, denominator) =
        (
            numerator * operand.numerator,
            denominator * operand.denominator
        );

    public void operator /=(Fraction operand)
    {
        if (operand.numerator == 0)
        {
            throw new DivideByZeroException();
        }
        (numerator, denominator) =
        (
            numerator * operand.denominator,
            denominator * operand.numerator
        );
    }

    public void operator ++() => numerator++;

    public void operator --() => numerator--;
}

public static class OperatorOverloading
{
    public static void Main()
    {
        var a = new Fraction(5, 4);
        var b = new Fraction(1, 2);
        Console.WriteLine(-a);   // output: -5 / 4
        Console.WriteLine(a + b);  // output: 14 / 8
        Console.WriteLine(a - b);  // output: 6 / 8
        Console.WriteLine(a * b);  // output: 5 / 8
        Console.WriteLine(a / b);  // output: 10 / 4
    }
}

Önceki örneği, 'den int'ye Fraction genişletebilirsiniz. Ardından, aşırı yüklenmiş işleçler bu iki türden gelen bağımsız değişkenleri destekler. Yani, bir tamsayıyı bir kesirle toplamak ve sonuçta bir kesir elde etmek mümkün hale gelir.

Özel tür dönüştürmesi tanımlamak için operator anahtar sözcüğünü de kullanırsınız. Daha fazla bilgi için bkz . Kullanıcı tanımlı dönüştürme işleçleri.

Aşırı yüklenebilir işleçler

Aşağıdaki tabloda aşırı yüklenebilen işleçler gösterilmektedir:

Operatörler Notlar
+x, -x, !x, , ~x, ++, --, true, false true ve false işleçleri birlikte aşırı yüklenmelidir.
x + y, x - y, x * y, , x / y, x % y,
x & y, x | y, x ^ y,
x << y, x >> y, x >>> y
x == y, x != y, x < y, , x > y, x <= y, x >= y aşağıdaki gibi çiftler halinde aşırı yüklenmelidir: == ve !=, < ve ><= ve >=.
+=, -=, , *=, /=, %=, &=, , \|=^=, <<=, >>=,>>>= Bileşik atama işleçleri C# 14 ve sonraki sürümlerde aşırı yüklenebilir.

Aşırı yüklenmiş bileşik atama operatörü aşağıdaki kurallara uymalıdır:

  • Değiştiriciyi public içermelidir.
  • Değiştiriciyi static içeremez.
  • Dönüş türü void olmalıdır.
  • Bildirim, bileşik atamanın sağ tarafını temsil eden bir parametre içermelidir.

C# 14'te başlayarak, artım (++) ve azaltma (--) işleçlerini örnek üyeleri olarak aşırı yükleyebilirsiniz. Örnek işleçleri, yeni bir örneğin oluşturulmasını önleyerek performansı geliştirebilir. Örnek işleci şu kurallara uymalıdır:

  • Değiştiriciyi public içermelidir.
  • Değiştiriciyi static içeremez.
  • Dönüş türü void olmalıdır.
  • Bu parametreler varsayılan değere sahip olsa bile herhangi bir parametre bildiremez.

Aşırı yüklenemez işleçler

Aşağıdaki tabloda aşırı yüklenemeyen işleçler gösterilmektedir.

Operatörler Alternatifler
x && y, x || y Hem true ve false işleçlerini, hem de & veya | işleçlerini aşırı yükleyin. Daha fazla bilgi için bkz. Kullanıcı tanımlı koşullu mantıksal işleçler.
a[i], a?[i] Dizin oluşturucu tanımlayın.
(T)x Bir cast ifadesi tarafından gerçekleştirilen özel tür dönüşümlerini tanımlayın. Daha fazla bilgi için bkz . Kullanıcı tanımlı dönüştürme işleçleri.
^x, x = y, x.y, , x?.y, c ? t : f, x ?? y, ??= y,
x..y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new,
sizeof, stackalloc, switch, typeof, , with
Yok.

C# 14'e geçmeden önce bileşik işleçler aşırı yüklenemez. karşılık gelen ikili işlecin aşırı yüklenmesi, ilgili bileşik atama işlecini örtük olarak aşırı yükler.

İşleç aşırı yükleme çözümlemesi

Önemli

Bu bölüm C# 14 ve üzeri için geçerlidir. C# 14'e geçmeden önce kullanıcı tanımlı bileşik atama işleçleri ile örnek artırma ve azaltma işleçlerine izin verilmez.

gibi x «op»= ybir bileşik atama ifadesinde değişken olarak sınıflandırılırsax, örnek işleçleri için «op»herhangi bir statik işleç üzerinde önceliklidir. türü x aşırı yüklenmiş «op»= bir işleç bildirmezse veya x değişken olarak sınıflandırılmazsa statik işleçler kullanılır.

sonek işleci ++ için, x değişken olarak sınıflandırılmazsa veya ifade kullanılırsa, örnek x++ yoksayılır. Aksi takdirde, operator ++ örneği tercih edilir. Örneğin

x++; // Instance operator++ preferred.
y = x++; // instance operator++ isn't considered.

Bu kuralın nedeni, yx atanması gerektiğidir. Derleyici, başvuru türündeki kullanıcı tanımlı bir uygulama için bunu belirleyemez.

Ön eki işleci ++ için, x++x içinde bir değişken olarak sınıflandırılırsa, örnek işleç statik bir unary operatör yerine tercih edilir.

C# dil belirtimi

Daha fazla bilgi için C# dil belirtimininaşağıdaki bölümlerine bakın:

Ayrıca bakınız