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);   // 调用<=操作符

  }

}

posted @ 2012-12-04 08:17  程序之魂  阅读(1273)  评论(0编辑  收藏  举报