Csharp/CSharp Tutorial/Operator Overload/operator overload
Содержание
A better way to overload !, |, and & for TwoDimension.
This version automatically enables the && and || operators.
<source lang="csharp">using System;
class TwoDimension {
int x, y; public TwoDimension() { x = y = 0; } public TwoDimension(int i, int j) { x = i; y = j; } // Overload | for short-circuit evaluation. public static TwoDimension operator |(TwoDimension op1, TwoDimension op2) { if( ((op1.x != 0) || (op1.y != 0) ) | ((op2.x != 0) || (op2.y != 0)) ) return new TwoDimension(1, 1); else return new TwoDimension(0, 0); } // Overload & for short-circuit evaluation. public static TwoDimension operator &(TwoDimension op1, TwoDimension op2) { if( ((op1.x != 0) && (op1.y != 0)) & ((op2.x != 0) && (op2.y != 0) ) ) return new TwoDimension(1, 1); else return new TwoDimension(0, 0); } // Overload !. public static bool operator !(TwoDimension op) { if(op) return false; else return true; } // Overload true. public static bool operator true(TwoDimension op) { if((op.x != 0) || (op.y != 0)) return true; // at least one coordinate is non-zero else return false; } // Overload false. public static bool operator false(TwoDimension op) { if((op.x == 0) && (op.y == 0)) return true; // all coordinates are zero else return false; } // Show X, Y public void show() { Console.WriteLine(x + ", " + y); }
}
class MainClass {
public static void Main() { TwoDimension a = new TwoDimension(5, 6); TwoDimension b = new TwoDimension(10, 10); TwoDimension c = new TwoDimension(0, 0); Console.Write("Here is a: "); a.show(); Console.Write("Here is b: "); b.show(); Console.Write("Here is c: "); c.show(); Console.WriteLine(); if(a) { Console.WriteLine("a is true."); } if(b) { Console.WriteLine("b is true."); } if(c) { Console.WriteLine("c is true."); } if(!a) { Console.WriteLine("a is false."); } if(!b) { Console.WriteLine("b is false."); } if(!c) { Console.WriteLine("c is false."); } Console.WriteLine(); Console.WriteLine("Use & and |"); if(a & b) Console.WriteLine("a & b is true."); else Console.WriteLine("a & b is false."); if(a & c) Console.WriteLine("a & c is true."); else Console.WriteLine("a & c is false."); if(a | b) Console.WriteLine("a | b is true."); else Console.WriteLine("a | b is false."); if(a | c) Console.WriteLine("a | c is true."); else Console.WriteLine("a | c is false."); Console.WriteLine(); // now use short-circuit ops Console.WriteLine("Use short-circuit && and ||"); if(a && b) Console.WriteLine("a && b is true."); else Console.WriteLine("a && b is false."); if(a && c) Console.WriteLine("a && c is true."); else Console.WriteLine("a && c is false."); if(a || b) Console.WriteLine("a || b is true."); else Console.WriteLine("a || b is false."); if(a || c) Console.WriteLine("a || c is true."); else Console.WriteLine("a || c is false."); }
}</source>
Here is a: 5, 6 Here is b: 10, 10 Here is c: 0, 0 a is true. b is true. c is false. Use & and | a & b is true. a & c is false. a | b is true. a | c is true. Use short-circuit && and || a && b is true. a && c is false. a || b is true. a || c is true.
Operator Overloading: A Complex Number Class
- If you overload the == operator, then you need to override Equals(object) and GetHashCode().
- The == operator and the Equals(object) methods should function the same way.
- When Equals() is overridden, you should also override GetHashCode().
- Equals() and GetHashCode should be compatible.
<source lang="csharp">using System;
struct Complex
{
float real; float imaginary; public Complex(float real, float imaginary) { this.real = real; this.imaginary = imaginary; } public float Real { get { return(real); } set { real = value; } } public float Imaginary { get { return(imaginary); } set { imaginary = value; } } public override string ToString() { return(String.Format("({0}, {1}i)", real, imaginary)); } public static bool operator==(Complex c1, Complex c2) { if ((c1.real == c2.real) && (c1.imaginary == c2.imaginary)) return(true); else return(false); } public static bool operator!=(Complex c1, Complex c2) { return(!(c1 == c2)); } public override bool Equals(object o2) { Complex c2 = (Complex) o2; return(this == c2); } public override int GetHashCode() { return(real.GetHashCode() ^ imaginary.GetHashCode()); } public static Complex operator+(Complex c1, Complex c2) { return(new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary)); } public static Complex operator-(Complex c1, Complex c2) { return(new Complex(c1.real - c2.real, c1.imaginary - c2.imaginary)); } public static Complex operator*(Complex c1, Complex c2) { return(new Complex(c1.real * c2.real - c1.imaginary * c2.imaginary, c1.real * c2.imaginary + c2.real * c1.imaginary)); } public static Complex operator/(Complex c1, Complex c2) { if ((c2.real == 0.0f) && (c2.imaginary == 0.0f)) throw new DivideByZeroException("Can"t divide by zero Complex number"); float newReal = (c1.real * c2.real + c1.imaginary * c2.imaginary) / (c2.real * c2.real + c2.imaginary * c2.imaginary); float newImaginary = (c2.real * c1.imaginary - c1.real * c2.imaginary) / (c2.real * c2.real + c2.imaginary * c2.imaginary); return(new Complex(newReal, newImaginary)); }
} class MainClass {
public static void Main() { Complex c1 = new Complex(3, 1); Complex c2 = new Complex(1, 2); Console.WriteLine("c1 == c2: {0}", c1 == c2); Console.WriteLine("c1 != c2: {0}", c1 != c2); Console.WriteLine("c1 + c2 = {0}", c1 + c2); Console.WriteLine("c1 - c2 = {0}", c1 - c2); Console.WriteLine("c1 * c2 = {0}", c1 * c2); Console.WriteLine("c1 / c2 = {0}", c1 / c2); }
}</source>
c1 == c2: False c1 != c2: True c1 + c2 = (4, 3i) c1 - c2 = (2, -1i) c1 * c2 = (1, 7i) c1 / c2 = (1, -1i)
Operator Overloading for your own class
<source lang="csharp">using System; struct MyType {
public MyType(int value) { this.value = value; } public override string ToString() { return(value.ToString()); } public static MyType operator -(MyType roman) { return(new MyType(-roman.value)); } public static MyType operator +( MyType roman1, MyType roman2) { return(new MyType(roman1.value + roman2.value)); } public static MyType operator ++(MyType roman) { return(new MyType(roman.value + 1)); } int value;
} class MainClass {
public static void Main() { MyType roman1 = new MyType(12); MyType roman2 = new MyType(125); Console.WriteLine("Increment: {0}", roman1++); Console.WriteLine("Increment: {0}", roman1++); Console.WriteLine("Addition: {0}", roman1 + roman2); Console.WriteLine("Addition: {0}", roman1++ + roman2++); }
}</source>
Increment: 12 Increment: 13 Addition: 139 Addition: 139
Valid Overloadable Operators
<source lang="csharp">C# Operator Overloadability +, -, !, ~, ++, --, true, false This set of unary operators can be overloaded. +, -, *, /, %, &, |, ^, <<, >> These binary operators can be overloaded. ==, !=, <, >, <=, >= The comparison operators can be overloaded. [] The [] operator cannot be overloaded. () The () operator cannot be overloaded. +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= Shorthand assignment operators cannot be overloaded.</source>