C# 参考之转换关键字:operator、explicit与implicit

operator

operator 关键字用于在类或结构声明中声明运算符。运算符声明能够采用下列四种形式之一:html

  1. public static result-type operator unary-operator ( op-type operand )
  2. public static result-type operator binary-operator (
        op-type operand,
        op-type2 operand2
        )
  3. public static implicit operator conv-type-out ( conv-type-in operand )
  4. public static explicit operator conv-type-out ( conv-type-in operand )

参数程序员

  1. result-type 运算符的结果类型。
  2. unary-operator 下列运算符之一:+ - ! ~ ++ — true false
  3. op-type 第一个(或惟一一个)参数的类型。
  4. operand 第一个(或惟一一个)参数的名称。
  5. binary-operator 其中一个:+ - * / % & | ^ << >> == != > < >= <=
  6. op-type2 第二个参数的类型。
  7. operand2 第二个参数的名称。
  8. conv-type-out 类型转换运算符的目标类型。
  9. conv-type-in 类型转换运算符的输入类型。

注意编程

  1. 前两种形式声明了用户定义的重载内置运算符的运算符。并不是全部内置运算符均可以被重载(请参见可重载的运算符)。op-type 和 op-type2 中至少有一个必须是封闭类型(即运算符所属的类型,或理解为自定义的类型)。例如,这将防止重定义整数加法运算符。
  2. 后两种形式声明了转换运算符。conv-type-in 和 conv-type-out 中正好有一个必须是封闭类型(即,转换运算符只能从它的封闭类型转换为其余某个类型,或从其余某个类型转换为它的封闭类型)。
  3. 运算符只能采用值参数,不能采用 ref 或 out 参数。
  4. C# 要求成对重载比较运算符。若是重载了==,则也必须重载!=,不然产生编译错误。同时,比较运算符必须返回bool类型的值,这是与其余算术运算符的根本区别。
  5. C# 不容许重载=运算符,但若是重载例如+运算符,编译器会自动使用+运算符的重载来执行+=运算符的操做。
  6. 运算符重载的其实就是函数重载。首先经过指定的运算表达式调用对应的运算符函数,而后再将运算对象转化为运算符函数的实参,接着根据实参的类型来肯定须要调用的函数的重载,这个过程是由编译器完成。
  7. 任何运算符声明的前面均可以有一个可选的属性(C# 编程指南)列表。

explicit

explicit 关键字用于声明必须使用强制转换来调用的用户定义的类型转换运算符。安全

static explicit operator target_type { source_type identifier }

参数ide

  1. target_type 目标类型
  2. source_type 源类型。
  3. identifier Something。

注意函数

  1. 转换运算符将源类型转换为目标类型。源类型提供转换运算符。与隐式转换不一样,必须经过强制转换的方式来调用显式转换运算符。若是转换操做可能致使异常或丢失信息,则应将其标记为 explicit。这能够防止编译器无提示地调用可能产生没法预见后果的转换操做。

implicit

implicit 关键字用于声明隐式的用户定义类型转换运算符。性能

static implicit operator target_type { source_type identifier }
注意
  1. 隐式转换能够经过消除没必要要的类型转换来提升源代码的可读性。可是,由于能够在程序员未指定的状况下发生隐式转换,所以必须注意防止使人不愉快的后果。通常状况下,隐式转换运算符应当从不引起异常而且从不丢失信息,以即可以在程序员不知晓的状况下安全使用它们。若是转换运算符不能知足那些条件,则应将其标记为 explicit。

示例ui

如下是一个综合示例,简要展现用法。如要更具体细节的了解,请参阅MSDN Library。spa

// keywords_operator.cs
/*
控制台输出:
r3 = ¥48元6角6分
float f = 48.66
r4 = ¥48元6角5分
*/

咱们会发现r4结果少了一分钱!这是由于在:htm

uint fen = (uint)(((f - yuan) * 100) % 10);

这句中,在将float转换为uint时发生了圆整错误(这与计算机以二进制存储有关)。解决这个错误,咱们可使用System.Convert类中用于处理数字的静态方法:

uint fen = Convert.ToUInt32(((f - yuan) * 100) % 10);

不过使用System.Convert处理会有些性能的损失。