最近在学习.net基础的东西,今晚上学习转换操作符方法,对类自定义隐式(显式)转换操作符进行了一些研究,发现了自定义隐式(显式)操作符需要注意的一个小问题。
我假设现在有个Rat类,如果要进行Rat r1 = 5; Int32 x = (Int32) r1; 我们需要给Rat类定义一个由一个Int32隐式构造一个Rat并返回的操作符,和一个由一个Rat显式构造一个Int32并返回操作符。
具体代码如下:


1

2

3

4



5

6

7

8

9

10



11

12

13

14

15

16



17

18

19

20

21

22



23

24

25

26

27

28



29

30

31

32

33

34



35

36



37

38

39

40

41

42

上面代码输出:
你可以发现我把其他类型转换成本类型时定义为隐式转换(Int32转换成Rat),把本类转换成其他类型时定义为显式转换(Rat转换成Int32)。
那么可以为Rat定义一个由一个Rat隐式构造一个Int32并返回方法吗?经过试验发现是可行的(,那么问题来了,假如Int32中同样定义了一个Rat隐式构造一个Int32并返回方法(ps:这里的意思是假如,毕竟Int32是元类型),此时进行一个Rat到Int32的隐式转换会出错吗?
(因为Int32是元类型,我们现在自定义一个Bat类替代Int32来继续试验)
出于好奇我写出下面的代码:


1

2

3



4

5

6



7

8

9

10

11



12

13

14

15

16

17



18

19

20



21

22

23

24

25



26

27

28

29

30

31



32

33



34

35

36

37

38

39

结果编译失败:
继续猜测如果不进行隐式转换,是不是两个类可以同时定义相同隐式转换呢?
注释Mian()内部分代码后:


1

2

3



4

5

6



7

8

9

10

11



12

13

14

15

16

17



18

19

20



21

22

23

24

25



26

27

28

29

30

31



32

33



34

35

36

37

38

39

结果编译成功,用ildasm工具打开编译后的198a.exe查看结果是
可以看到类Bat和Rat都有一个叫olmplicit:class Bat(class Rat)的隐式转换操作定义。那么内部定义是否一样呢?
点击查看如下:
可以看出是完全一样的两个隐式转换定义。
ok把试验进行到底,现在把Rat类中隐式定义去掉:


using System;
class Bat
{
public Int32 numR;
public Bat(Int32 numr)
{
numR = numr;
}
public static implicit operator Bat(Rat r)
{
return new Bat(22222222);
}
}
class Rat
{
public Int32 numR;
public Rat(Int32 numr)
{
numR = numr;
}
//public static implicit operator Bat(Rat r)
//{
// return new Bat(1111111);
//}
}
class App
{
static void Main()
{
Rat r1 = new Rat(5);
Bat b1 = r1;
System.Console.WriteLine(r1.numR.ToString());
System.Console.WriteLine(b1.numR.ToString());
}
}
编译成功,并运行得到如下图结果:
可以看到Clr成功的调用了Bat类中定义的隐式Rat转换Bat的操作
我们用ildasm查看编译结果:
再把Bat的隐式转换去掉,让Rat类中存在一个隐式转换。
编译成功,运行结果是:
好了现在来总结下:C#没有对隐式(显式)转换操作的定义位置强制要求,但是你会发现不当的定义将会发生错误,假设下如果几个小组同时进行开发每个小组都有自己的程序集,如果对隐式(显式)转换操作的定义没有个统一的规范会带来错误,我们是不是应该建议这么定义隐式(显式)转换操作:把其他类型转换成本类型时全部定义为隐式式转换,把本类转换成其他类型时定义全部进行显示转换。(ps:也许这个问题早就有规范了只是我不知道呵呵,深夜沪被小雨洗刷的这么安静,我顶着感冒,享受着思考带来的快乐)