C# 基础知识系列之 操作符重载
C#操作符重载是什么?
是指允许用户使用用户定义的类型编写表达式的能力。
如果有一个复数Complex类对一元操作符“++”重载,可以写成:
public static Complex operator ++(Complex a)
{
…
}
对二元操作符“+”可以写成:
public static Complex operator +(Complex a, Complex b)
{
…
}
一元操作符有一个参数,二元操作符有二个参数。重载操作符开始必须以public static修饰。可以重载的操作符包括:
一元操作符:+ - ! ~ ++ -- true false
二元操作符:+ - * / % & | ^ << >> == != > < >= <=
下面的操作符要求同时重载,不能重载中间的单独一个:
一元操作符:true和false
二元操作符:== 和!=, >和<, >=和<=
操作符重载给类的一些操作带来了方便。两个复数的实部相加运算写成:
public static double Add(complex a, complex b)
{
return a.r+b.r
}
这样的写法不够简洁,并且类的成员修饰符不为public时就不能这样直接的操作。
操作符重载的实现
using System;
class Complex
{
double r, v; //r+ v i
public Complex(double r, double v)
{
this.r=r;
this.v=v;
}
// 二元操作符”+”重载
public static Complex operator +(Complex a, Complex b)
{
return new Complex(a.r+b.r, a.v+b.v);
}
// 一元操作符”-”重载
public static Complex operator -(Complex a)
{
return new Complex(-a.r,-a.v);
}
// 一元操作符”++”重载
public static Complex operator ++(Complex a)
{
double r=a.r+1;
double v=a.v+1;
return new Complex(r, v);
}
public void Print()
{
Console.Write(r+" + "+v+"i\n");
}
}
class Test
{
public static void Main()
{
Complex a=new Complex(3,4);
Complex b=new Complex(5,6);
Complex c=-a;
c.Print();
Complex d=a+b;
d.Print();
a.Print();
Complex e=a++; // 先赋值后++
a.Print();
e.Print();
Complex f=++a; // 先++后赋值
a.Print();
f.Print();
}
}
在操作符重载中,返回值往往需要“new”一个新的complex对象。
另外一种的操作符重载类型是用户定义的数据类型转换,它实现不同类型之间的转换,包括显式转换和隐式转换两种方式。
编程中往往需要将一个类型转换成另外一个类型。例如将int转换成double,它们是系统已经预定义的类型,编译器知道如何来执行它们的转换, 具体内容在下一节“类型转换”中讨论。如果它们中间有的类型不是编译器预定义的类型,编译器将不知道执行转换,解决的方法是使用用户定义的数据类型转换。
转换过程不会丢失数据而出现异常,就采用隐式转换。如果转换过程有可能丢失数据,就要采用显式转换。
隐式类型转换的写法如:
public static implicit operator Square(double s)
{
…
}
实现double向Square转换功能。关键字explicit实现显式类型转换:
public static explicit operator double(Square s)
{
…
}
using System;
class Square
{
private double Side;
public Square(int s)
{
Console.WriteLine("int类型参数构造函数");
Side=(double)s;
}
public Square(double s)
{
Console.WriteLine("double类型参数构造函数");
Side=s;
}
// 重写object类的ToString()方法.
public override string ToString()
{
Console.WriteLine("重写object类的ToString()方法");
return this.Side.ToString();
}
// 重载”+” 操作符,参数为两个square类
public static Square operator + (Square x,Square y)
{
Console.WriteLine("重载+操作符,参数为两个square类");
return new Square(x.Side+y.Side);
}
// 重载”+”操作符,参数一个为square类,一个为double类型
public static Square operator + (Square x,double y)
{
Console.WriteLine("重载+操作符,参数一个为square类,一个为double类型");
return new Square(x.Side+y);
}
// 重载”+”操作符,参数一个为square类,一个为int类型
public static Square operator + (Square x,int y)
{
Console.WriteLine("重载+操作符,参数一个为square类,一个为int类型");
return x +(double)y; //调用上面的重载”+”操作符
}
// 隐式类型转换,实现double类型转换为Square
public static implicit operator Square(double s)
{
Console.WriteLine("隐式类型转换,实现double类型转换为Square ");
return new Square(s);
}
// 隐式类型转换,实现int类型转换为Square
public static implicit operator Square(int s)
{
Console.WriteLine("隐式类型转换,实现int类型转换为Square ");
return new Square((double)s);
}
// 重载” == ”操作符
public static bool operator ==(Square x,Square y)
{
Console.WriteLine("重载== 操作符,两个参数都为square类");
return x.Side==y.Side;
}
// 重载” !=”操作符
public static bool operator !=(Square x,Square y)
{
Console.WriteLine("重载!=操作符,两个参数都为square类");
return !(x==y); //调用前面的重载”==”操作符
}
// 当重载”==”和”!=”的同时还要重载object类的GetHashCode()和Equals(),否则编译器会出现警告
// 也可以不重写这两个方法,对运行结果没有影响
public override bool Equals(object o)
{
return this==(Square)o;
}
public override int GetHashCode()
{
return (int)Side;
}
// 重载” > ”操作符
public static bool operator >(Square x,Square y)
{
Console.WriteLine("重载 >操作符,两个参数都为square类");
return x.Side>y.Side;
}
// 重载” <”操作符
public static bool operator <(Square x,Square y)
{
Console.WriteLine("重载<操作符,两个参数都为square类");
return x.Side<y.Side;
}
// 重载” <= ”操作符
public static bool operator <=(Square x,Square y)
{
Console.WriteLine("重载<=操作符,两个参数都为square类");
return (x<y) || (x==y); //调用重载的操作符” ==”和”<”
}
// 重载” >=”操作符
public static bool operator >=(Square x,Square y)
{
Console.WriteLine("重载>=操作符,两个参数都为square类");
return (x>y) || (x==y); //调用重载的操作符” ==”和” >”
}
public static void Main()
{
Square s1=new Square(10);
Square s2=new Square(20);
Square s3=s1+s2; // 调用operator + (Square,Square)
Console.WriteLine(s3); // 调用重写object类的ToString()方法
Console.WriteLine(s3+15); // 调用重写的operator + (Square,int)以及ToString()
Console.WriteLine(s3+1.5); // 调用重写的operator + (Square,double)和ToString()
s3=10; // 调用隐式转换public static implicit operator Square(int )
Console.WriteLine(s3);
Square s4=10;
Console.WriteLine(s1==s4); // 调用== 操作符
Console.WriteLine(s1!=s4); // 调用 != 操作符
Console.WriteLine(s1>s2); // 调用 >操作符
Console.WriteLine(s1<=s4); // 调用<=操作符
}
}