当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > C#中的两个+(plus)操作符解析

ASP.NET
asp+的页面指示标识
亲密接触ASP+(1)
亲密接触ASP+(2)
使用纯粹的asp+语言制作的栏目管理(二)
使用纯粹的asp+语言制作的栏目管理(三)
利用asp+的独特的底层操作的功能实现对Pop服务器的存取(实现了asp+收pop信件的功能)
C#中的函数重载
开发者面临的.Net挑战(二)
ASP中是如何使用存储过程的
深入讲解 ASP+ 验证(一)
深入讲解 ASP+ 验证(二)
深入讲解 ASP+ 验证(三)
深入讲解 ASP+ 验证(四)
ASP.NET强大的性能(一)
ASP.NET强大的性能(二)
ASP.NET多语言支持
ASP.NET升级能力探讨(一)
ASP.NET升级能力探讨(二)
ASP.NET升级能力探讨(三)
ASP.NET超凡的代码控制(一)

ASP.NET 中的 C#中的两个+(plus)操作符解析


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 282 ::
收藏到网摘: n/a

  C#中,我们一般情况下认为"+"操作符有两种功能,一种是做算术加,一种是做字符串的连接。今天看到一份文档说,深入解析C#中两个PLUS操作符执行的不同操作,想了想,也的确应该是这样,IL代码实例也表面这个观点是正确的:

  我们先写一小段测试代码:

  namespace MSILTest
  {
  class Program
  {
  static void Main(string[] args)
  {
  string a = "aaa";
  string b = a + "bbb";
  System.Console.WriteLine(b);
  int c = 1;
  int d = c + 1;
  System.Console.WriteLine(d);
  }
  }
  }

  反编译得到IL代码:

  .method private hidebysig static void Main(string[] args) cil managed
  {
  .entrypoint
  // Code size 40 (0x28)
  .maxstack 2
  .locals init ([0] string a,
  [1] string b,
  [2] int32 c,
  [3] int32 d)
  IL_0000: nop
  IL_0001: ldstr "aaa"
  IL_0006: stloc.0
  IL_0007: ldloc.0
  IL_0008: ldstr "bbb"
  IL_000d: call string [mscorlib]System.String::Concat(string,
  string)
  IL_0012: stloc.1
  IL_0013: ldloc.1
  IL_0014: call void [mscorlib]System.Console::WriteLine(string)
  IL_0019: nop
  IL_001a: ldc.i4.1
  IL_001b: stloc.2
  IL_001c: ldloc.2
  IL_001d: ldc.i4.1
  IL_001e: add
  IL_001f: stloc.3
  IL_0020: ldloc.3
  IL_0021: call void [mscorlib]System.Console::WriteLine(int32)
  IL_0026: nop
  IL_0027: ret
  } // end of method Program::Main

  从上面的代码中可以看到,在+连接字符串的时候,C#的Complier是把它转换成为了带两个参数的Concat()函数。这个函数可以反编译System.dll可以看到这个静态的带两个参数的方法。

  而+在handle两个number的时候,是直接转换成为add操作指令的。

  这“两个”操作指令,完全没有一点相似的地方。所以,我们需要把这不同功能的两个+当成是两个运算符来看待。

  同时,我们还可以稍为引申一下,关于C#中的强制类型转换:

  大家看这一句:

  IL_0021: call void [mscorlib]System.Console::WriteLine(int32)

  如果我们把

  System.Console.WriteLine(d);

  改成

  System.Console.WriteLine('\u0041');

  相应的IL代码就会转变成为:

  IL_0020: ldc.i4.s 65
  IL_0022: call void [mscorlib]System.Console::WriteLine(char)

  由此我们可以得到结论:

  强制类型转换,只不过是调用了一些方法的不同的重载的方法,而这个值本身是没有变的。

  这个值在Stack的顶部,转换前后都不变,只是编译器来根据强制类型转换相应的代码来选择不同方法的不同的重载版本。

  跟踪堆栈顶部数值,得到的结果也支持我们的这个结论。