情景导入
假设有这样一个情景:类school表示学校,其中含有成员studentNum,表示学校中学生数量。现在有两个学校s1、s2,s1学校中学生人数为100,s2学校中学生人数为150,需要得到两个学校学生总人数。可以试着使用成员函数获取两学校的人数后相加,或者创建成员函数实现获取两个学校学生总人数的功能。本实例试着使用第二种方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace code
{
public class school
{
int studentNum;
public school(int studentNum)
{
this.studentNum = studentNum;
}
public school()
{
studentNum = 0;
}
public void studentNumSet(int studentNum)
{
this.studentNum = studentNum;
}
/*
public static int operator +(school s1,school s2)
{
return s1.studentNum + s2.studentNum;
}
*/
public int studentNumAdd(school s2)
{
return this.studentNum + s2.studentNum;
}
}
public class Caller
{
public static void Main(string[] args)
{
school s1 = new school(100);
school s2 = new school(150);
int sum = s1.studentNumAdd(s2);
Console.WriteLine("学生总人数为" + sum);
Console.ReadKey();
}
}
}
输出结果如下:
学生总人数为250
运算符重载
运算符重载,指重定义或重载 C# 中内置的运算符,使之可以实现对象之间直接的运算。重载运算符实际上是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。与其他函数一样,重载运算符有返回类型和参数列表。
运算符重载语法如下:
public static <返回值类型> operator <操作符>(<操作对象参数1>,<操作对象参数2>...){
//逻辑处理
//...
return <返回值>
}
其中运算符需要用静态修饰符static
限定;返回值类型与实际操作符有关;操作数对象作为传参,传参数目与操作符相关,例如+
操作符为二元操作符,那么参数需要两个操作对象。
例如上面给出的情景,需要计算两个学校学生人数总和,如果可以通过运算符+直接将s1、s2相加,则计算人数总和的方式更加简单易懂。此时可以借助于运算符重载功能,将运算符+重载,从而实现希望的功能。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace code
{
public class school
{
int studentNum;
public school(int studentNum)
{
this.studentNum = studentNum;
}
public school()
{
studentNum = 0;
}
public void studentNumSet(int studentNum)
{
this.studentNum = studentNum;
}
public static int operator +(school s1,school s2) //运算符+重载,实现两学校对象相加,返回两学校学生人数总和功能
{
return s1.studentNum + s2.studentNum;
}
public int studentNumAdd(school s2)
{
return this.studentNum + s2.studentNum;
}
}
public class Caller
{
public static void Main(string[] args)
{
school s1 = new school(100);
school s2 = new school(150);
int sum = s1 + s2;
Console.WriteLine("学生总人数为" + sum);
Console.ReadKey();
}
}
}
此代码中,运算符+为二目运算符,且操作结果为int型,因此操作数有两个,返回值类型为int。将运算符重载后,即可使用运算符+直接对两学校对象相加。
运行新程序,输出结果相同,可见重载运算符可行。
运算符重载规则
运算符重载有以下规则:
- x+y,x-y,x*y,x/y,x&y,x%y,x|y,x^y,x>>y,x<<y,x>>>y这些运算符可以重载;
- +x,-x,!x,~x,++,--,true,false可以重载,其中true与false必须同时重载,不能单独重载其中一个;
- x>y,x<y,x==y,x!=y,x>=y,x<=y可以重载,但是必须保证以下重载运算符同时重载:x>y与x<y,x==y与x!=y,x>=y与x<=y;
- x&&y,x||y不能重载,可以试图通过x|y,x&y,true,false间接代替其功能;
- a[i]不能重载,该功能可以用索引器代替;
- +=,-=,*=,/=,%=,|=,&=,^=,>>=,<<=,>>>=不能直接重载,当重载对应二元运算符时,这些运算符同时自动重载;
- 其他运算符一般不可重载。
下面是多个运算符重载的实例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace code
{
public class myInt //myInt简单模拟int类型的少数操作
{
int num; //存储对象值
public myInt(int num)
{
this.num = num;
}
public static int operator +(myInt num1,myInt num2) //重载运算符+
{
return num1.num + num2.num;
}
public static int operator -(myInt num1,myInt num2) //重载运算符-
{
return num1.num - num2.num;
}
public static bool operator >(myInt num1,myInt num2) //重载运算符>
{
return num1.num > num2.num;
}
public static bool operator <(myInt num1,myInt num2) //重载运算符<
{
return num1.num < num2.num;
}
}
public class Caller
{
public static void Main(string[] args)
{
myInt a = new myInt(10);
myInt b = new myInt(13);
Console.WriteLine("a + b = "+(a+b));
Console.WriteLine("a - b = "+(a-b));
if (a > b)
Console.WriteLine("a > b is true");
else
Console.WriteLine("a > b is false");
if (a < b)
Console.WriteLine("a < b is true");
else
Console.WriteLine("a < b is false");
Console.ReadKey();
}
}
}
上面的实例重载了多个运算符,并对myInt类对象a、b操作以测试重载是否成功,输出结果如下:
a + b = 23
a - b = -3
a > b is false
a < b is true
通过该实例,可以熟悉运算符重载规则与语法。