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

ASP.NET
ASP.NET 多附件上传实现代码
asp.net 类库中使用ConfigurationManager.ConnectionStrings
asp.net AjaxControlToolKit--TabContainer控件的介绍
ASP.NET环境下为网站增加IP过滤功能
asp.net访问Access数据库溢出错误
ASP.NET AJAX 4.0的模版编程(Template Programming)介绍
asp.net StringBuilder的用法 实例代码
asp.net Accee数据库连接不稳定解决方案
ASP.NET2.0 SQL Server数据库连接详解
asp.net Repeater之非常好的数据分页
C# 生转换网页为pdf
浅谈ASP.NET的Postback 实例代码
asp.net Ext grid 显示列表
通过ASP.net实现flash对数据库的访问
如何创建一个AJAXControlToolKit的扩展控件
asp.net 简单验证码验证实现代码
asp.net 在客户端显示服务器端任务处理进度条的探讨
Asp.net treeview实现无限级树实现代码
asp.net INI文件读写类
asp.net下检测SQL注入式攻击代码

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


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

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