C#で演算子のオーバーロードを処理する方法
ポリモーフィズムは、OOP(オブジェクト指向プログラミング)の基本原則の1つです。ポリモーフィズムという言葉は、多くを意味する「ポリ」と形を意味する「モーフ」の2つの言葉から派生しています。したがって、ポリモーフィズムは、同じものが異なる形で存在することを意味します。
演算子のオーバーロードは、静的ポリモーフィズムの例です。演算子のオーバーロードを活用したり、演算子に機能を追加して、基本的なデータ型を操作するのとほぼ同じ方法でユーザー定義型を操作できます。
演算子とは何ですか?また、オーバーロードできる演算子は何ですか?
式には通常、演算子とオペランドがあります。演算子はオペランドを操作する演算子であり、すべて式の一部です。例として、以下は2つのオペランドと1つの演算子を含む式です。オペランドはXとYで、演算子は+です。
X + Y
演算子は、その目的と演算子が機能するオペランドの数に応じて、単項、2進数、比較、割り当てなどに分類されます。ほとんどの演算子はオーバーロードされる可能性がありますが、特定の制限が適用されます。本質的に、すべての演算子がオーバーロードできるわけではありません。
単項演算子、つまり1つのオペランドで機能する演算子はオーバーロードされる可能性があります。二項演算子や、==、!= 、、 =などの比較演算子をオーバーロードすることもできます。ただし、=、?、->、new、is、sizeof、またはtypeof演算子をオーバーロードすることはできません。&&や||などの条件演算子をオーバーロードすることもできません。簡単に。また、配列インデックス演算子[]はオーバーロードできません。
このMSDNの記事から、すべての演算子をオーバーロードできるものについて詳しく知ることができます。
C#での演算子のオーバーロードの実装
このセクションでは、C#で演算子のオーバーロードを実装する方法について説明します。DistanceCalculatorという名前の次のクラスについて考えてみます。
public class DistanceCalculator
{
Int32 feet = 0, inch = 0;
public DistanceCalculator(Int32 feet = 0, Int32 inch = 0)
{
this.feet = feet;
this.inch = inch;
}
}
上記のコードリストを参照してください。DistanceCalculatorクラスには、Int32型の2つのデータメンバー、つまりフィートとインチが含まれています。ここで、このクラスにさらにメソッドを追加して、演算子をオーバーロードする方法を説明します。
演算子のオーバーロードを使用する場合は、特定の点に注意する必要があります。オーバーロードされる演算子には、キーワード演算子でマークされた対応するメソッドが必要です。演算子関数の引数はオペランドであり、演算子関数は値を返すことができます。演算子関数は静的であり、包含型のメンバーである必要があります。
次のコードスニペットは、一般的な演算子関数がどのように見えるかを示しています。この例は、==および!=演算子をオーバーロードする方法を示しています。
public static bool operator ==(DistanceCalculator obj1, DistanceCalculator obj2)
{
return obj1.Value == obj2.Value;
}
public static bool operator !=(DistanceCalculator obj1, DistanceCalculator obj2)
{
return obj1.Value != obj2.Value;
}
Valueは、インチ単位で値を返すプロパティであることに注意してください。
public Int32 Value
{
get
{
return (feet * 12) + inch;
}
}
これがDistanceCalculatorクラスの完全なコードリストです。
public class DistanceCalculator
{
Int32 feet = 0, inch = 0;
public DistanceCalculator(Int32 feet = 0, Int32 inch = 0)
{
this.feet = feet;
this.inch = inch;
}
public static bool operator ==(DistanceCalculator obj1, DistanceCalculator obj2)
{
return obj1.Value == obj2.Value;
}
public static bool operator !=(DistanceCalculator obj1, DistanceCalculator obj2)
{
return obj1.Value != obj2.Value;
}
public override bool Equals(object obj)
{
DistanceCalculator distanceCalculator = obj as DistanceCalculator;
if (distanceCalculator != null)
{
return (distanceCalculator == this);
}
return false;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public Int32 Feet
{
get { return feet; }
}
public Int32 Inch
{
get { return inch; }
}
public Int32 Value
{
get
{
return (feet * 12) + inch;
}
}
}
次のコードスニペットは、DistanceCalculatorクラスの使用方法を示しています。
static void Main(string[] args)
{
DistanceCalculator obj1 = new DistanceCalculator(1, 2);
DistanceCalculator obj2 = new DistanceCalculator(1, 2);
Console.WriteLine((obj1 == obj2).ToString());
Console.Read();
}
次のコードスニペットは、+演算子をオーバーロードして2つのオブジェクトを追加する方法を示しています。
public static DistanceCalculator operator +(DistanceCalculator obj1, DistanceCalculator obj2)
{
Int32 totalInches = obj1.Value + obj2.Value;
Int32 feet = totalInches / 12;
Int32 inch = totalInches % 12;
DistanceCalculator temp = new DistanceCalculator(feet, inch);
return temp;
}
次の2つのプロパティをDistanceCalculatorクラスに追加しましょう。次のコードスニペットは、DistanceCalculatorタイプの2つのオブジェクトを追加し、結果のオブジェクトを同じタイプとして返す方法を示しています。つまり、返されるオブジェクトは、DistanceCalculatorタイプです。
public Int32 Feet
{
get { return feet; }
}
public Int32 Inch
{
get { return inch; }
}
これは、DistanceCalculatorクラスの2つのインスタンスを作成し、オーバーロードされた演算子関数を利用して、同じタイプの別のオブジェクトに結果を割り当てる方法です。
static void Main(string[] args)
{
DistanceCalculator obj1 = new DistanceCalculator(1, 11);
DistanceCalculator obj2 = new DistanceCalculator(1, 2);
DistanceCalculator obj3 = obj1 + obj2;
Console.WriteLine("Feet: "+obj3.Feet.ToString());
Console.WriteLine("Inch: " + obj3.Inch.ToString());
Console.Read();
}