Csharp/CSharp Tutorial/Operator Overload/operator overload
Версия от 15:31, 26 мая 2010; (обсуждение)
Содержание
A better way to overload !, |, and & for TwoDimension.
This version automatically enables the && and || operators.
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.");
}
}
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.
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);
}
}
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
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++);
}
}
Increment: 12 Increment: 13 Addition: 139 Addition: 139
Valid Overloadable Operators
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.