C#重载操作符的那点事

如时实现C#操作符重载。

先写关键词public和static,后跟返回类型,后跟operator关键词,后跟要声明的操作符符号,最后在对一对圆括号中添加恰当的参数。

C#操作符重载方法:

1、编写操作符重载方法。

2、实例化后,进行操作符运算

下边用C#操作符重载代码进行说明:

  internal struct Hour
{
private int Value;

public Hour(int ivalue)
{
this.Value = ivalue;
}
//定义个属性用于取Value的值。
public int iValue {
get { return Value; }
set { Value = value; }
}
//声明一个二元操作符,将两个Hour相加
public static Hour operator +(Hour ihs, Hour rhs)
{
return new Hour(ihs.Value + rhs.Value);
}
/* 操作符是public的。所有操作符都必须是public的
操作符是static的。所有操作符都必须是static的,操作永远不具有多态性,
面且不能使用virtual、abstract、override或者sealed修饰符。
二元操作符(比如+)有两个显式参数;一元操作符有一个显式的参数
我们有了public Hour(int iValue)构造函数,就可以将一个int与Hour相加,
只是首先要将int转换成为Hour hour a= ; int b= ; Hour sum=a+new Hour(b);
虽然上述代码完全有效,但相较于让一个Hour和一个int直接相加它即不清晰也不准确。
为了使Hour可以+ int,必须声明一个二元操作符+,它的第一个参数是Hour,第二个参数是一个int。
C#操作符重载
*/
public static Hour operator +(int ihs, Hour rhs)
{
return rhs + new Hour(ihs);//这里调用上一个Hour的 (Hour+Hour)+ 重载
}
public static Hour operator +( Hour rhs,int ihs)
{
return ihs + rhs;//这里调用上一个Hour的 (int,Hour) + 重载
}

/*C#中,下列操作符都是可以重载的:

+ - ! ~ ++ -- true false

* / % & | ^ << >> == != > < >= <=

但也有一些操作符是不允许进行重载的,如:

=,&&,||,?:,new,typeof,sizeof,is

一元操作符重载

顾名思义,一元操作符重载时操作符只作用于一个对象,此时参数表为空,当前对象作为操作符的单操作数。
*/
public static Hour operator ++(Hour huValue)
{
huValue.iValue++; return huValue;
} //C#操作符重载
//==操作符是二元操作符,必须带有两个参数
public static bool operator==(Hour lhs,Hour rhs)
{
return lhs.iValue == rhs.iValue;
}
/*二元操作符重载

大多数情况下我们使用二元操作符重载。这时参数表中有一个参数,
当前对象作为该操作符的左操作数,参数作为操作符的右操作数。

下面我们给出二元操作符重载的一个简单例子,即笛卡儿坐标相加。
*/
public static bool operator !=(Hour lhs, Hour rhs)
{
return lhs.iValue != rhs.iValue;
}

}
class Program
{
/*C#操作符:<、>;==、!=;true、false必须成对出现,即重载了“<”就必须重载“>”,重载了“==”就必须重载“!=”,重载了“true”就必须重载“false”;*/
static void Main()
{
Hour h = new Hour(30);
Hour p = new Hour(50);

Hour add = h + p;//(Hour+Hour)
add = h.iValue + p;//(int,Hour)
add = h + p.iValue;//(Hour ,int)
add++;//++(Hour)
Console.WriteLine(add.iValue);

Console.ReadKey();
}
//这个方法被jit编译时,BeforeFieldInit和Precise类的类型构造器还没被执行,所以对这些构造器的调用将嵌入这个方法的代码中,使它的运行变得较慢。
private static void PerfTest1(int iterations)
{
Stopwatch sw = Stopwatch.StartNew();
for (int x = 0; x < iterations; x++)
{
//jit编译器优化调用BeforeFileldInit的类型构造器的代码,使它在循环之前执行。
BeforefieldInit.s_x = 1;
}
Console.WriteLine("PerfTest1:{0} BeforeFileldInit", sw.Elapsed);
sw = Stopwatch.StartNew();
for (int x = 0; x < iterations; x++)
{
//jit编译器在这里生成调用Precise类的类型构造器的代码,所以在每次循环迭代,都要核实一遍是否需要调用构造器。
Precise.s_x = 1;
}
Console.WriteLine("PerfTest1:{0} Precise", sw.Elapsed);
}
//这个方法被jit编译时,BeforeFieldInit和Precise类的类型构造器已经被执行,所以这个方法的代码中,不会在生成对这些构造器的调用,它运行的更快。

private static void PerfTest2(int iterations)
{
Stopwatch sw = Stopwatch.StartNew();
for (int x = 0; x < iterations; x++)
{
BeforefieldInit.s_x = 1;
}
Console.WriteLine("PerfTest2:{0} BeforeFileldInit", sw.Elapsed);
sw = Stopwatch.StartNew();
for (int x = 0; x < iterations; x++)
{
Precise.s_x = 1;
}
Console.WriteLine("PerfTest2:{0} Precise", sw.Elapsed);
}
}

C#编程语言要求操作符重载方法有一个参数的类型与当前定一个这个方法的类型相同。这样的限制是为了使C#编译器在合理的时间内找到要绑定的操作符方法。

posted @ 2011-12-01 11:17  Rookier  阅读(1209)  评论(0编辑  收藏  举报