有段时间,老弄不明白操作符在CLR 中是怎样调用的。在操作Int32,String, 等基元类型时,有时候要对两个Int32 类型的数据相加,或对String 类型相加,相减等。编译器是怎样识别“+ ”,“- ”的呢?这些基元类型难道对这些操作符做了定义吗?我Reflector 一下,发现String 类型中没有对操作符方法进行定义,怪了!
去CLI 查查,发现编译器对基元类型的操作符方法做了集成,也就是说不需要在类型中去定义操作符方法,编译器已经定义。也好,省事,免得每个类型都要去定义,性能也提升了。
无意中,鼠标点到decimal 类型,也属于CLR 的基元,看到这样一些方法;
反编译op_UnaryPlus(Decimal):Decimal 方法,发现;
public static decimal operator + (decimal d)
{
return d;
}
竟然对操作符方法进行了重写。
而且重写的操作符方法都以public,static 修饰;方法名前都有operator 关键字。再看“< ”号操作符;
public static bool operator < (decimal d1, decimal d2)
{
return (
Compare
(d1, d2) < 0);
}
效果一样。
再看“* ”号;
public static decimal operator * (decimal d1, decimal d2)
{
return
Multiply
(d1, d2);
}
还一样
可以看到,虽然编译器集成了基元操作符的方法,但是如果你想重写也是可以的。
做个demo 玩玩;
namespace Operator操作符方法
{
class Namer
{
private string FirstName;
private string LastName;
public Namer()
{
this.Init(null, null);
}
public Namer(string fn, string ln)
{
this.Init(fn, ln);
}
private void Init(string fn, string ln)
{
this.FirstName = fn;
this.LastName = ln;
}
/// <summary>
/// 重载运算符>
/// </summary>
/// <param name="n1"></param>
/// <param name="n2"></param>
/// <returns></returns>
public static bool operator >(Namer n1, Namer n2)
{
return (n1.FirstName.CompareTo(n2.FirstName) > 0 && n1.LastName.CompareTo(n2.LastName) > 0);
}
/// <summary>
/// 重载运算符<
/// </summary>
/// <param name="n1"></param>
/// <param name="n2"></param>
/// <returns></returns>
public static bool operator <(Namer n1, Namer n2)
{
return (n1.FirstName.CompareTo(n2.FirstName) < 0 && n1.LastName.CompareTo(n2.LastName) < 0);
}
/// <summary>
/// 重写方法,必须有
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
return base.Equals(obj);
}
/// <summary>
/// 重写方法,必须有
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "姓:" + this.FirstName + " 名:" + this.LastName;
}
}
}
再定义使用Namer类型的Program类
namespace Operator操作符方法
{
class Program
{
static void Main(string[] args)
{
Namer m1=new Namer("a","b");
Console.WriteLine(m1.ToString());
Console.WriteLine("m1对象哈西值"+m1.GetHashCode());
Namer m2 = new Namer("c", "d");
Console.WriteLine(m2.ToString());
Console.WriteLine("m2对象哈西值" + m2.GetHashCode());
if(m1>m2)
{
Console.WriteLine("m1>m2");
}
else
{
Console.WriteLine("m1<m2");
}
Console.ReadLine();
}
}
}
查看结果
通过跟踪,发现确实执行我自己定义的public static bool operator >(Namer n1, Namer n2)方法,OK
总结;
修饰符,必须用public,static;操作符方法要成对的被重载;必须实现System.Object的getHashCode()和Equal(Object obj)虚方法。
去CLI
无意中,鼠标点到decimal
![](https://i-blog.csdnimg.cn/blog_migrate/0e8ec5588a8fc1068657c7829476bea7.gif)
反编译op_UnaryPlus(Decimal):Decimal
public static decimal
{
return d;
}
竟然对操作符方法进行了重写。
而且重写的操作符方法都以public,static
public static bool
{
return (
}
效果一样。
再看“*
public static decimal
{
return
}
还一样
可以看到,虽然编译器集成了基元操作符的方法,但是如果你想重写也是可以的。
做个demo
namespace Operator操作符方法
{
class Namer
{
private string FirstName;
private string LastName;
public Namer()
{
this.Init(null, null);
}
public Namer(string fn, string ln)
{
this.Init(fn, ln);
}
private void Init(string fn, string ln)
{
this.FirstName = fn;
this.LastName = ln;
}
/// <summary>
/// 重载运算符>
/// </summary>
/// <param name="n1"></param>
/// <param name="n2"></param>
/// <returns></returns>
public static bool operator >(Namer n1, Namer n2)
{
return (n1.FirstName.CompareTo(n2.FirstName) > 0 && n1.LastName.CompareTo(n2.LastName) > 0);
}
/// <summary>
/// 重载运算符<
/// </summary>
/// <param name="n1"></param>
/// <param name="n2"></param>
/// <returns></returns>
public static bool operator <(Namer n1, Namer n2)
{
return (n1.FirstName.CompareTo(n2.FirstName) < 0 && n1.LastName.CompareTo(n2.LastName) < 0);
}
/// <summary>
/// 重写方法,必须有
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
return base.Equals(obj);
}
/// <summary>
/// 重写方法,必须有
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "姓:" + this.FirstName + " 名:" + this.LastName;
}
}
}
再定义使用Namer类型的Program类
namespace Operator操作符方法
{
class Program
{
static void Main(string[] args)
{
Namer m1=new Namer("a","b");
Console.WriteLine(m1.ToString());
Console.WriteLine("m1对象哈西值"+m1.GetHashCode());
Namer m2 = new Namer("c", "d");
Console.WriteLine(m2.ToString());
Console.WriteLine("m2对象哈西值" + m2.GetHashCode());
if(m1>m2)
{
Console.WriteLine("m1>m2");
}
else
{
Console.WriteLine("m1<m2");
}
Console.ReadLine();
}
}
}
查看结果
![](https://i-blog.csdnimg.cn/blog_migrate/6f656dd0dce95cd8fe843bb5e7013e51.gif)
通过跟踪,发现确实执行我自己定义的public static bool operator >(Namer n1, Namer n2)方法,OK
总结;
修饰符,必须用public,static;操作符方法要成对的被重载;必须实现System.Object的getHashCode()和Equal(Object obj)虚方法。