操作符重载

有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成把两个整数加到一起的代码。

当编译器发现两个string类型的实例使用+操作符的时候,编译器会生成把两个字符串连接到一起的代码。那么编译器怎么就会知道这样做呢?如何进行操作符重载呢?

下面C#代码展示了一个类中如何进行操作符重载:

namespace DoNet.Seven.ConsoleApplicationTest
{class Program{static void Main(string[] args){rational r1 = new rational(10);rational r2 = new rational(5);rational r3= r1 + r2;Console.WriteLine(r3.Value);Console.ReadKey();}}//有理数public sealed class rational{private int _value = 0;public int Value{get { return _value; }set { _value = value; }}public rational(int value){this._value = value;}public rational(){}public static rational operator+(rational num1,rational num2){rational result = new rational(num1.Value+num2.Value);return result;}}
}

运行代码输入结果是15

用IL工具看下编译器生成的代码如下:

1、首先CLR规范要求操作符重载方法必须是public和static方法。另外,C#编译器要求操作符重载方法至少有一个参数的类型与当前定义的这个方法的类型相同。之所以这样做,

是为了是编译器能在合理的时间内找到要绑定的操作符方法。

2、编程语言的编译器看到源码中出现一个+操作符时,会检查是否有一个操作数的类型定义了一个名为op_Addtion的specialname方法,而且该方法的参数兼容于操作数的类型,

如果存在这样的一个方法,编译器就生成调用它的代码。如果不存在这样的一个方法,就生成一个编译错误。

3、对于其它操作符编译之后对应的方法如下表所示(左边是一元操作符,右边是二元操作符)

                                

转换操作符

当设计一个类型时应该考虑到和其它类型之间的转换,这个其实很重要,将对我们的编码有很大的好处,就像每个类型都会有的一个方法Tostring()一样,我们定义一个int类型,可以很方便的用tostring()方法把

int转换为string,当然也可以转换为其它类型。就像上面的rational一样,如果能将一个int或者double转换为一个rational,就会很方便,反之亦然。

 //有理数public sealed class rational{private int _value = 0;public int Value{get { return _value; }set { _value = value; }}public rational(int value){this._value = value;}public rational(double value){this._value =(int)value;}public rational(){}public int ToInt(){return _value;}public double ToDouble(){return (double)_value;}public static rational operator+(rational num1,rational num2){rational result = new rational(num1.Value+num2.Value);return result;}}

1、调用这些构造器和方法,开发人员可以很方便的将int和double对象转换成rational对象,这将给编程工作带来很多方便。设计类型时,应该认真考虑类型需要支持的转换构造器和方法。

2、int i=10;long j=i;这样的代码我们经常会看到,那么从int类型到long类型的转换为什么就可以隐士的进行呢?这就涉及到了我们的转换操作符,下面我们也为rational定义几个转换操作符。

namespace DoNet.Seven.ConsoleApplicationTest
{class Program{static void Main(string[] args){int n = 10;rational r1 = n;double d=(double)r1;Console.WriteLine(r1.Value);Console.WriteLine(d.ToString());Console.ReadKey();}}//有理数public sealed class rational{private int _value = 0;public int Value{get { return _value; }set { _value = value; }}public rational(int value){this._value = value;}public rational(double value){this._value =(int)value;}public rational(){}public int ToInt(){return _value;}public double ToDouble(){return (double)_value;}public static rational operator+(rational num1,rational num2){rational result = new rational(num1.Value+num2.Value);return result;}public static implicit operator rational(int value){return new rational(value);}public static implicit operator rational(double value){return new rational(value);}public static explicit operator int(rational value){return value.ToInt();}public static explicit operator double(rational value){return value.ToDouble();}}
}

输出的结果是10、10。 我们可以在rational、int、double之间来回转换,是不是觉得挺方便的,在这个过程中,编译器又帮我们做了什么呢?

在C#中,implicit关键字告诉编译器为了生成代码来调用方法,不需要在源代码中进行显示转换,相反,explicit关键字告诉编译器只有在发现了显示转型时,才调用方法。

在implicit或explicit关键字之后,要指定operator关键字告诉编译器该方法是一个转换操作符。在operator之后,指定对象要转换成什么类型。在圆括号内,则指定要从什么类型转换。

C#编译器检测到代码中的转型,并内部生成IL代码来调用rational类型定义的转换操作符方法,如果用反编译器看的话可以发现,转换操作符方法会生成下面这样的代码:

结论

不论是操作符重载还是转换操作符,都是在设计类型是考虑到我们编码方便而设计的,下面我们看下C#中decimal类型中的定义。

转载于:https://www.cnblogs.com/skm-blog/p/4229487.html

C#中如何利用操作符重载和转换操作符相关推荐

  1. 走进C++程序世界------操作符运算、操作符重载、转换运算符、双目元算、+=,-+运算符,比较运算符及下标运算符

    重载,在一个类定义中,可以编写几个同名的方法,但是只要它们的签名参数列表不同,Java就会将它们看做唯一的方法.简单的说,一个类中的方法与另一个方法同名,但是参数表不同,这种方法称之为重载方法 下面关 ...

  2. C++面向对象操作符重载:调用操作符和函数对象

    1.定义了调用操作符的类,其对象常称为函数对象,即它们是行为类似函数的对象. 可以为类类型的对象重载函数调用操作符.一般为表示操作的类重载调用操作符.函数调用操作符必须声明为成员函数.一个类可以定义函 ...

  3. 【Groovy】集合遍历 ( 操作符重载 | 集合中的 “ << “ 操作符重载 | 使用集合中的 “ << “ 操作符添加一个元素 | 使用集合中的 “ << “ 操作符添加一个集合 )

    文章目录 一.集合中的 " << " 操作符重载 1.使用集合中的 " << " 操作符添加一个元素 2.使用集合中的 " & ...

  4. C++中的指针特征操作符重载

    文章目录 1 C++中的指针特征操作符重载 1.1 指针特征操作符重载 1.2 使用指针特征操作符重载实现智能指针 1 C++中的指针特征操作符重载 1.1 指针特征操作符重载 指针特征操作符重载: ...

  5. C++中的赋值操作符重载

    文章目录 1 C++中的赋值操作符重载 1.1 赋值操作符重载 1 C++中的赋值操作符重载 1.1 赋值操作符重载 关于赋值操作符: 编译器为每个类默认重载了赋值操作符. 默认的赋值操作符仅完成浅拷 ...

  6. 操作符重载——C/C++学习笔记

    此篇文章来自于网上,作为自己学习中的笔记,若有侵权行为,请告之,24小时之内必删除!下面就转入正题吧! 一.什么是操作符重载? 一看到重载,很容易就让人联想到成员函数重载,函数重载可以使名称相同的函数 ...

  7. C#锐利体验-第八讲 索引器与操作符重载(转)

    第八讲 索引器与操作符重载 南京邮电学院 李建忠(cornyfield@263.net) 索引 C#锐利体验 "Hello,World!"程序 C#语言基础介绍 Microsoft ...

  8. 【C++ 语言】类型转换 ( 转换操作符 | const_cast | static_cast | dynamic_cast | reinterpret_cast | 字符串转换 )

    文章目录 I . const_cast 转换操作符 II . static_cast 转换操作符 III . dynamic_cast 转换操作符 IV . reinterpret_cast 转换操作 ...

  9. c++ operator百样操作符重载(详解)

    目录 一.operator== :等号判断重载 二.operator = : 等号赋值重载 三.operator != : 不等于重载 四.operator> : 大于号 或者 小于号 重载 五 ...

最新文章

  1. AI 医生正式上岗了?AI 医疗结合迎爆发点!
  2. 关于学习Python的一点学习总结(57->正则表达式及re模块中的一些函数)
  3. 你应该掌握的七种回归技术
  4. 使用个性化Profile代替Session
  5. Python dataframe列拆分多行与统计
  6. mysql 存取字符集_MySQL字符集设置—MySQL数据库乱码问题详解
  7. 我理解的Future模式
  8. 实战-动手开发第一个区块链投票DAPP
  9. 什么软件能打开prt文件_prt文件除了UG和PROE还可以用什么软件打开?
  10. 德标螺纹规格对照表_国标德标对照表
  11. VS2012(Visual Studio 2012)官方免费中文旗舰版下载(含激活密钥)
  12. 自然语言表示简史(BERT/ELMO/Word2vec/LDA/Bow/Ohehot,词向量、句向量、优缺点、应用与解决的问题)
  13. Winform实现读写IC卡Demo源码含注释
  14. 嵌入式开发日记(3)——利用Python接收并处理JY61传感器数据
  15. 软件项目风险控制-公益讲座视频,供大家学习参考。
  16. jfinal,jxl导出excel遇到的异常
  17. 网络技术——网络管理技术
  18. 基于ROS搭建简易软件框架实现ROV水下目标跟踪(补1)--gazebo仿真
  19. 卸载百度软件修复服务器,快速修复win7系统笔记本卸载百度软件中心助手的解决教程...
  20. Graphics2D(1) : 查看系统所有字体

热门文章

  1. Golang实践录:利用反射reflect构建通用打印结构体接口
  2. 遇到一个日志文件变化带来的文件句柄问题
  3. Linux移植随笔:对tslib库的ts_test测试程序代码的一点分析
  4. 深度学习入门读书笔记:Day-14
  5. linux串口查看mxser,Ubuntu8.04安装CP-168U的串口连接问题
  6. 【Flink】Flink 小知识点 Flink 同时 保存 offset 到backend 和 kafka 内置 topic
  7. 【ElasticSearch】ES 的 path.data 配置多个盘的路径,查询效率与单个存储盘的效率比,哪个效率高些?
  8. 【mac】mac 安装 RibbitMQ 报错 Error when reading /Users/lcc/.erlang.cookie: eacces
  9. 【Spring】SpringMVC 初始化 流程
  10. 【MySQL】MySQL常见的读写分离方法