重载转换运算符

  除了重载上述数学运算符外,还可以定义类型之间的隐式和显式转换。如果要在不相关的类型之间转换,例如类型之间没有继承关系,也没有共享接口,就必须这么做。

  下面定义ConvClass1和ConvClass2之间的隐式转换,即编写下列代码:

  1. ConvClass1 op1 = new ConvClass1();
  2. ConvClass2 op2 = op1;

  另外,可以定义一个显式转换:

  1. ConvClass1 op1 = new ConvClass1();
  2. ConvClass2 op2 = (ConvClass2)op1;

  例如,考虑下面的代码:

  1. public class ConvClass1
  2. {
  3. public int val;
  4. public static implicit operator ConvClass2(ConvClass1 op1)
  5. {
  6. ConvClass2 returnVal = new ConvClass2();
  7. returnVal.val = op1.val;
  8. return returnVal;
  9. }
  10. }
  11. public class ConvClass2
  12. {
  13. public double val;
  14. public static explicit operator ConvClass1(ConvClass2 op1)
  15. {
  16. ConvClass1 returnVal = new ConvClass1();
  17. checked
  18. {
  19. returnVal.val = (int)op1.val;
  20. };
  21. return returnVal;
  22. }
  23. }

  其中,ConvClass1包含一个int值,ConvClass2包含一个double值。int值可以隐式转换为double值,所以可以在ConvClass1和ConvClass2之间定义一个隐式转换。但反过来就不行了,应把ConvClass2和ConvClass1之间的转换定义为显式转换。

  在代码中,用关键字implicitexplicit来指定这些转换,如上所示。对于这些类,下面的代码就很好:

  1. ConvClass1 op1 = new ConvClass1();
  2. op1.val = 3;
  3. ConvClass2 op2 = op1;

  但反向转换需要进行下述显式数据类型转换:

  1. ConvClass2 op1 = new ConvClass2();
  2. op1.val = 3e15;
  3. ConvClass1 op2 = (ConvClass1)op1;

  如果在显式转换中使用了checked关键字,则上述代码将产生一个异常,因为op1val属性值太大,不能放在op2val属性中。