操作符是C#中用于定义类的实例对象间表达式操作的一种成员。和索引器类似,操作符仍然是对方法实现
的一种逻辑界面抽象,也就是说在编译成的IL中间语言代码中,操作符仍然是以方法的形式调用的。在类
内定义操作符成员又叫操作符重载。C#中的重载操作符共有三种:一元操作符,二元操作符和转换操作符
。并不是所有的操作符都可以重载,三种操作符都有相应的可重载操作符集,列于下表:
一元操作符 + - ! ~ ++ -- true false
二元操作符 + - * / % & | ^ << >> == != > < >= <=
转换操作符 隐式转换()和显式转换()
操作符重载是指允许用户使用用户定义的类型编写表达式的能力。
例如,通常需要编写类似于以下内容的代码,以将两个数字相加。很明显,sum 是两个数字之和。
int i = 5;
int sum = i + j;
如果可以使用代表复数的用户定义的类型来编写相同类型的表达式,那当然是最好不过了:
Complex i = 5;
Complex sum = i + j;
运算符重载允许为用户定义的类型重载(即指定明确的含义)诸如“+”这样的运算符。如果不进行重载
,则用户需要编写以下代码:
Complex i = new Complex(5);
Complex sum = Complex.Add(i, j);
此代码可以很好地运行,但 Complex 类型并不能象语言中的预定义类型那样发挥作用。
操作符重载语法:
语法:
public static 返回值类型 operator 操作符 (类型)
实例:
public static Fraction operator +(Fraction lhs, Fraction rhs)
{
}
分数操作符重载
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharptest
{
/// <summary>
/// 分式
/// </summary>
class Fraction
{
private int denominator;//分母
private int numerator;//分子
public Fraction(int _numerator, int _denominator)
{
Denominator = _denominator;
Numerator = _numerator;
}
public int Denominator
{
get { return denominator; }
set { denominator = value; }
}
public int Numerator
{
get { return numerator; }
set { numerator = value; }
}
public Fraction(int _numerator)
: this(_numerator, 1)
{
//denominator = _denominator;
//numerator = _numerator;
}
/// <summary>
/// 重载+
/// </summary>
/// <param name="a">Fraction</param>
/// <param name="b">Fraction</param>
/// <returns>Fraction</returns>
public static Fraction operator +(Fraction a, Fraction b)
{
if (a.denominator == b.denominator)//若分母相等
{
return new Fraction(a.numerator + b.numerator, a.denominator);
}
else
{
return new Fraction(a.numerator * b.denominator + b.numerator *
a.denominator,
a.denominator * b.denominator);
}
}
/// <summary>
/// 重写ToString方法
/// </summary>
/// <returns>string</returns>
public override string ToString()
{
if (denominator == 1)//分母为1 直接返回分子
{
return numerator.ToString();
}
else//分数表达式
{
return numerator.ToString() + "/" + denominator.ToString();
}
}
/// <summary>
/// 隐式转换为Fraction
/// </summary>
/// <param name="a"></param>
/// <returns>Fraction</returns>
public static implicit operator Fraction(int a)
{
return new Fraction(a);
}
/// <summary>
/// 显示转换为INT
/// </summary>
/// <param name="a"></param>
/// <returns>int</returns>
public static explicit operator int(Fraction a)
{
return a.numerator / a.denominator;
}
}
}
调用:
Fraction f1 = new Fraction(2, 3);
Fraction f2 = new Fraction(2, 7);
Fraction f3 = f1 + f2;
Console.WriteLine(f3.ToString());
Console.ReadLine();
结果: 20/21
implicit为隐式转换操作符重载
explicit为显示转换操作符重载
创建有用的操作符:
任何事情都有特定的时间和场所,操作符重载是一个容易引起误解的语言功能,而且编程人员对待它的态
度也大相径庭。一些人认为:用户使用这一功能编写的程序将令人费解,而且它也不应归于编程语言。另
一些人则认为它是一个很不错的功能,在任何地方都可以使用。 这两种观点既包含正确的成分,但也有
欠妥之处。应该承认,运算符重载可能会导致编写出的程序令人费解,但根据我的经验,即使不使用运算
符重载,也很可能编写出令人费解的代码。在某些情况下,不使用重载甚至会使代码更加令人费解。那些
不分场合、随意使用重载的人“确实”在生产令人费解的代码。
在语言中之所以使用重载,是为了在概念上对用户的类或结构进行简化。只有在有助于提高用户所写代码
的可读性时,才能对运算符进行重载。请注意,我们所说的检验标准是“更清晰”,而不是“更简短”。
运用了运算符重载的类几乎总是会使代码变得更简短,但并不能每次都使代码变得更清晰(即可读性更强
)。
参考:
http://blog.youkuaiyun.com/nuaalfm/archive/2007/08/08/1732927.aspx
http://blog.youkuaiyun.com/luqinghua/archive/2007/03/12/1526970.aspx