Operatör Aşırı Yükleme (Operator Overloading) Nedir?Beğendin
Operatör Aşırı Yükleme, birli (unary) "+, -, !, ~, ++, -- gibi", ikili (binary) "+, -, *, /, %, &, |, ^, <<, >>" ve karşılaştırma "==, !=, <, >, <=, >=" operatörlerinin, bizim tarafımızdan tanımlanmış karmaşık sınıflarda nasıl uygulanacağına dair yeniden tanımlanmasıdır. Basit bir örnek ile anlatacak olursak:
public class Matrix2D
{
private readonly int _rowCount;
private readonly int _columnCount;
private readonly double[,] _matrix;
public double this[int row, int column]
{
get { return _matrix[row, column]; }
set { _matrix[row, column] = value; }
}
public Matrix2D(double[,] matrix)
{
_matrix = matrix;
_rowCount = matrix.GetLength(0);
_columnCount = matrix.GetLength(1);
}
public override string ToString()
{
var stringBuilder = new StringBuilder();
for (var i = 0; i < _rowCount; i++)
{
for (var j = 0; j < _columnCount; j++)
{
stringBuilder.Append(_matrix[i, j].ToString("F1").PadLeft(5));
stringBuilder.Append(" ");
}
stringBuilder.AppendLine();
}
return stringBuilder.ToString().TrimEnd('\r', '\n');
}
}
Yukarıda Matrix2D adlı 2 boyutlu matrisleri temsil eden bir sınıf tanımladık. Bu matris sınıfının ikili toplama (+) işlemi için operatör önyüklemesini aşağıdaki şekilde yazabiliriz.
public static Matrix2D operator +(Matrix2D matrix1, Matrix2D matrix2)
{
if (matrix1._rowCount != matrix2._rowCount || matrix1._columnCount != matrix2._columnCount)
{
throw new NotSupportedException();
}
var resultMatrix = new Matrix2D(new double[matrix1._rowCount, matrix1._columnCount]);
for (var i = 0; i < matrix1._rowCount; i++)
{
for (var j = 0; j < matrix1._columnCount; j++)
{
resultMatrix._matrix[i, j] = matrix1._matrix[i, j] + matrix2._matrix[i, j];
}
}
return resultMatrix;
}
Aynı şekilde matris çıkarma (-) işlemi için de aşağıdaki şekilde yazabiliriz.
public static Matrix2D operator -(Matrix2D matrix1, Matrix2D matrix2)
{
if (matrix1._rowCount != matrix2._rowCount || matrix1._columnCount != matrix2._columnCount)
{
throw new NotSupportedException();
}
var resultMatrix = new Matrix2D(new double[matrix1._rowCount, matrix1._columnCount]);
for (int i = 0; i < matrix1._rowCount; i++)
{
for (int j = 0; j < matrix1._columnCount; j++)
{
resultMatrix._matrix[i, j] = matrix1._matrix[i, j] - matrix2._matrix[i, j];
}
}
return resultMatrix;
}
Bunlardan farklı olarak matrisin sabit çarpan ile çarpım işlemini de aşağıdaki gibi kodlayalım. Burada işlem sağdan çarpım ve soldan çarpım olarak ayrı ayrı kodlanmalıdır. (C:sabit ve A:Matris ise C*A ve A*C işlemi farklı işlemlerdir.) Biz sadece soldan çarpımı kodladık.
public static Matrix2D operator *(double constant, Matrix2D matrix1)
{
var resultMatrix = new Matrix2D(new double[matrix1._rowCount, matrix1._columnCount]);
for (var i = 0; i < matrix1._rowCount; i++)
{
for (var j = 0; j < matrix1._columnCount; j++)
{
resultMatrix._matrix[i, j] = constant * matrix1._matrix[i, j];
}
}
return resultMatrix;
}
Buna ek olarak "static Matrix2D operator *(Matrix2D matrix1,double constant)" metodunun da tanımlanması gerekecek. Son olarak 2 matris çarpım metodunun da aşağıdaki gibi kodlayabilirsiniz. Matematiksel kısmı size bıraktım.
public static Matrix2D operator *(Matrix2D matrix1, Matrix2D matrix2)
{
if (matrix1._rowCount != matrix2._columnCount || matrix1._columnCount != matrix2._rowCount)
{
throw new NotSupportedException();
}
var resultMatrix = new Matrix2D(new double[matrix1._rowCount, matrix2._columnCount]);
//TODO: Implement multiplication here
throw new NotImplementedException();
return resultMatrix;
}
Tüm operatör tanımlarını, ana uygulamada aşağıdaki gibi basitçe kullanabiliriz.
var matrix1 = new Matrix2D(new[,]
{
{2.3, 4.1},
{1.7, 2.1},
{3.3, 5.2}
});
var matrix2 = new Matrix2D(new[,]
{
{2.7, 1.3},
{1.9, 2.7},
{1.3, 0.9}
});
var addMatrix = matrix1 + matrix2;
var subMatrix = matrix1 - matrix2;
var mulMatrix1 = 0.5 * matrix1;
//var mulMatrix2 = matrix1 * 0.5 This line will not compile. Because we did not define this operator in this way.
Operatör aşırı yüklemeleri public, static olmak zorundadır. bu tip operatörlerin tanımlanması, üst katman geliştiricileri tarafında geliştirme maliyetini azaltmakla birlikte, kod okunabilirliğini artırmaktadır. "+=", "-=" gibi kendi ile işlem yapan operatörler de bu tanımları kullanacaklardır.
Örnek uygulama kodlarına buradan ulaşabilirsiniz.