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

ASP.NET
在C#中导入WebBrowser控件,生成具有强名称的程序集
Asp.Net中的脚本回调和Server.Transfer页面传值
暂时性的解决datagrid控件数据绑定时候xxx字段不属于xxx表的错误
http://www.donews.net/yangwl/archive/2004/10/17/136872.aspx
Some tips for using visual studio .net
Grasshopper简介(节选)
ORACLE 常用的SQL语法和数据对象
[DNN学习所得]让IE也能实现解压缩功能(提供演示源码下载)
学习笔记之Microsoft Windows服务
关于XML:以对象模型为中心
P&P Enterprise Library Extensions
简易的字符替换,可以用于用户自我介绍输入框,简单新闻回复& etc.
缩略图多路径多格式保存
"关机/休眠/重启/注销"的类
[DNN功能]自己动手做语言包
处理WinForm多线程程序时的陷阱
获得光标在多行textbox中的行与列的函数
ADO.NET 和 ADO 的比较
vb.net类的封装,继承,多态,抽象之一
Display XML in AxSHDocVw.AxWebBrowser

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 194 ::
收藏到网摘: 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的顶部,转换前后都不变,只是编译器来根据强制类型转换相应的代码来选择不同方法的不同的重载版本。

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