<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>战神部落 /*专注DotNet、前端开发技术*/</title>
	<atom:link href="http://www.topzs.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.topzs.com</link>
	<description>扬起你的笑脸,把影子藏在身后!</description>
	<lastBuildDate>Tue, 29 Nov 2011 14:06:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Log4Net使用指南</title>
		<link>http://www.topzs.com/tech-box/microsoft_tech/csharp_develop/log4net_shi_yong_zhi_nan</link>
		<comments>http://www.topzs.com/tech-box/microsoft_tech/csharp_develop/log4net_shi_yong_zhi_nan#comments</comments>
		<pubDate>Tue, 05 Jul 2011 02:57:16 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[C# Develop]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[Log4Net]]></category>

		<guid isPermaLink="false">http://www.topzs.com/?p=997</guid>
		<description><![CDATA[声明：本文内容主要译自Nauman Leghari的Using log4net，亦加入了个人的一点心得(节3.1.4)。 请在这里下载示例代码 1 简介 1.1 Log4net的优点： 几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后，就不太可能再利用专门的调试工具了。然而一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的问题。 经验表明，日志记录往往是软件开发周期中的重要组成部分。它具有以下几个优点：它可以提供应用程序运行时的精确环境，可供开发人员尽快找到应用程序中的Bug；一旦在程序中加入了Log 输出代码，程序运行过程中就能生成并输出日志信息而无需人工干预。另外，日志信息可以输出到不同的地方（控制台，文件等）以备以后研究之用。 Log4net就是为这样一个目的设计的，用于.NET开发环境的日志记录包。 1.2 Log4net的安装： 用户可以从http://logging.apache.org/log4net/下载log4net的源代码。解压软件包后，在解压的src目录下将log4net.sln载入Visual Studio .NET，编译后可以得到log4net.dll。用户要在自己的程序里加入日志功能，只需将log4net.dll引入工程即可。 &#160; 2 Log4net的结构 log4net 有四种主要的组件，分别是Logger（记录器）, Repository（库）, Appender（附着器）以及 Layout（布局）. 2.1 Logger 2.1.1 Logger接口 Logger是应用程序需要交互的主要组件，它用来产生日志消息。产生的日志消息并不直接显示，还要预先经过Layout的格式化处理后才会输出。 Logger提供了多种方式来记录一个日志消息，你可以在你的应用程序里创建多个Logger，每个实例化的Logger对象都被log4net框架作为命名实体(named entity)来维护。这意味着为了重用Logger对象，你不必将它在不同的类或对象间传递，只需要用它的名字为参数调用就可以了。log4net框架使用继承体系，继承体系类似于.NET中的名字空间。也就是说，如果有两个logger,分别被定义为a.b.c和a.b，那么我们说a.b是a.b.c的祖先。每一个logger都继承了祖先的属性 Log4net框架定义了一个ILog接口，所有的logger类都必须实现这个接口。如果你想实现一个自定义的logger，你必须首先实现这个接口。你可以参考在/extension目录下的几个例子。 ILog接口的定义如下： public interface ILog { void Debug(object message); void Info(object message); void Warn(object message); void Error(object message); void Fatal(object message); //以上的每一个方法都有一个重载的方法，用来支持异常处理。 //每一个重载方法都如下所示，有一个异常类型的附加参数。 void Debug(object message, [...]]]></description>
			<content:encoded><![CDATA[<p>声明：本文内容主要译自Nauman Leghari的Using log4net，亦加入了个人的一点心得(节3.1.4)。<br />
请在这里下载<a href="http://files.cnblogs.com/dragon/Log4NetTester.rar">示例代码</a></p>
<p><strong>1 </strong><strong>简介</strong></p>
<p><strong>1.1 </strong><strong>Log4net</strong><strong>的优点：</strong></p>
<p>几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后，就不太可能再利用专门的调试工具了。然而一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的问题。</p>
<p>经验表明，日志记录往往是软件开发周期中的重要组成部分。它具有以下几个优点：它可以提供应用程序运行时的精确环境，可供开发人员尽快找到应用程序中的Bug；一旦在程序中加入了Log 输出代码，程序运行过程中就能生成并输出日志信息而无需人工干预。另外，日志信息可以输出到不同的地方（控制台，文件等）以备以后研究之用。</p>
<p>Log4net就是为这样一个目的设计的，用于.NET开发环境的日志记录包。</p>
<p><strong>1.2 </strong><strong>Log4net</strong><strong>的安装：</strong></p>
<p>用户可以从<a href="http://logging.apache.org/log4net/">http://logging.apache.org/log4net/</a>下载log4net的源代码。解压软件包后，在解压的src目录下将log4net.sln载入Visual Studio .NET，编译后可以得到log4net.dll。用户要在自己的程序里加入日志功能，只需将log4net.dll引入工程即可。</p>
<p>&nbsp;</p>
<p><strong>2 </strong><strong>Log4net</strong><strong>的结构</strong></p>
<p>log4net 有四种主要的组件，分别是Logger（记录器）, Repository（库）, Appender（附着器）以及 Layout（布局）.</p>
<p><strong>2.1 </strong><strong>Logger</strong></p>
<p><strong>2.1.1 </strong><strong>Logger</strong><strong>接口</strong></p>
<p>Logger是应用程序需要交互的主要组件，它用来产生日志消息。产生的日志消息并不直接显示，还要预先经过Layout的格式化处理后才会输出。</p>
<p>Logger提供了多种方式来记录一个日志消息，你可以在你的应用程序里创建多个Logger，每个实例化的Logger对象都被log4net框架作为命名实体(named entity)来维护。这意味着为了重用Logger对象，你不必将它在不同的类或对象间传递，只需要用它的名字为参数调用就可以了。log4net框架使用继承体系，继承体系类似于.NET中的名字空间。也就是说，如果有两个logger,分别被定义为a.b.c和a.b，那么我们说a.b是a.b.c的祖先。每一个logger都继承了祖先的属性<span id="more-997"></span></p>
<p>Log4net框架定义了一个ILog接口，所有的logger类都必须实现这个接口。如果你想实现一个自定义的logger，你必须首先实现这个接口。你可以参考在/extension目录下的几个例子。</p>
<p>ILog接口的定义如下：</p>
<pre>public interface ILog
{
  void Debug(object message);
  void Info(object message);
  void Warn(object message);
  void Error(object message);
  void Fatal(object message);

//以上的每一个方法都有一个重载的方法，用来支持异常处理。
//每一个重载方法都如下所示，有一个异常类型的附加参数。
  void Debug(object message, Exception ex);
  // ...

//Boolean 属性用来检查Logger的日志级别
//（我们马上会在后面看到日志级别）
  bool isDebugEnabled;
  bool isInfoEnabled;
  //… 其他方法对应的Boolean属性
}</pre>
<p>&nbsp;</p>
<p><!--more-->Log4net框架定义了一个叫做LogManager的类，用来管理所有的logger对象。它有一个GetLogger()静态方法，用我们提供的名字参数来检索已经存在的Logger对象。如果框架里不存在该Logger对象，它也会为我们创建一个Logger对象。代码如下所示：</p>
<p>log4net.ILog log = log4net.LogManager.GetLogger(“logger-name”);</p>
<p>通常来说，我们会以类（class）的类型（type）为参数来调用GetLogger()，以便跟踪我们正在进行日志记录的类。传递的类(class)的类型(type)可以用typeof(Classname)方法来获得，或者可以用如下的反射方法来获得：</p>
<p>System.Reflection.MethodBase.GetCurrentMethod().DeclaringType</p>
<p>尽管符号长了一些，但是后者可以用于一些场合，比如获取调用方法的类(class)的类型(type)。</p>
<p><strong>2.1.2 </strong><strong>日志的级别</strong></p>
<p>正如你在ILog的接口中看到的一样，有五种不同的方法可以跟踪一个应用程序。事实上，这五种方法是运作在Logger对象设置的不同日志优先级别上。这几种不同的级别是作为常量定义在log4net.spi.Level类中。你可以在程序中使用任何一种方法。但是在最后的发布中你也许不想让所有的代码来浪费你的CPU周期，因此，框架提供了7种级别和相应的Boolean属性来控制日志记录的类型。</p>
<p>&nbsp;</p>
<p>Level有以下几种取值</p>
<table border="1" cellpadding="0">
<tbody>
<tr>
<td width="69"><strong>级别</strong></td>
<td width="118"><strong>允许的方法</strong></td>
<td width="154"><strong>Boolean</strong><strong>属性</strong></td>
<td width="81"><strong>优先级别</strong></td>
</tr>
<tr>
<td width="69"><strong>OFF</strong></td>
<td width="118"></td>
<td width="154"></td>
<td width="81"><strong>Highest</strong></td>
</tr>
<tr>
<td width="69"><strong>FATAL</strong></td>
<td width="118"><strong>void Fatal(&#8230;);</strong></td>
<td width="154"><strong>bool IsFatalEnabled;</strong></td>
<td width="81"></td>
</tr>
<tr>
<td width="69"><strong>RROR</strong></td>
<td width="118"><strong>void Error(&#8230;);</strong></td>
<td width="154"><strong>bool IsErrorEnabled;</strong></td>
<td width="81"></td>
</tr>
<tr>
<td width="69"><strong>WARN</strong></td>
<td width="118"><strong>void Warn(&#8230;);</strong></td>
<td width="154"><strong>bool IsWarnEnabled;</strong></td>
<td width="81"></td>
</tr>
<tr>
<td width="69"><strong>INFO</strong></td>
<td width="118"><strong>void Info(&#8230;);</strong></td>
<td width="154"><strong>bool IsInfoEnabled;</strong></td>
<td width="81"></td>
</tr>
<tr>
<td width="69"><strong>DEBUG</strong></td>
<td width="118"><strong>void Debug(&#8230;);</strong></td>
<td width="154"><strong>bool IsDebugEnabled;</strong></td>
<td width="81"></td>
</tr>
<tr>
<td width="69"><strong>ALL</strong></td>
<td width="118"></td>
<td width="154"></td>
<td width="81"><strong>Lowest</strong></td>
</tr>
</tbody>
</table>
<p>表1  Logger的日志级别</p>
<p>在log4net框架里，通过设置配置文件，每个日志对象都被分配了一个日志优先级别。如果没有给一个日志对象显式地分配一个级别，那么该对象会试图从他的祖先继承一个级别值。</p>
<p>ILog接口的每个方法都有一个预先定义好了的级别值。正如你在表1看到的，ILog的Inof()方法具有INFO级别。同样的，以此类推，Error()方法具有ERROR级别。当我们使用以上的任何一种方法时，log4net框架会检查日志对象logger的级别和方法的级别。只有当方法的级别高于日志级别时，日志请求才会被接受并执行。</p>
<p>举例说明，当你创建了一个日志对象，并且把他的级别设置为INFO。于是框架会设置日志的每个Boolean属性。当你调用相应的日志方法时，框架会检查相应的Boolean属性，以决定该方法能不能执行。如下的代码：</p>
<pre class="brush:csharp">Logger.Info("message");
Logger.Debug("message");
Logger.Warn("message");</pre>
<p>&nbsp;</p>
<p>于第一种方法，Info()的级别等与日志的级别（INFO），因此日志请求会被传递，我们可以得到输出结果”message”。</p>
<p>对于第二种方法，Debug()的级别低于日志对象logger的日志级别(INFO)，因此，日志请求被拒绝了，我们得不到任何输出。同样的，针对第三行语句，我们可以很容易得出结论。</p>
<p>在表1中有两个特殊的级别：ALL和OFF。ALL表示允许所有的日志请求。OFF是拒绝所有的请求。</p>
<p>你也可以显式地检查Logger对象的Boolean属性，如下所示：</p>
<pre class="brush:csharp">if (logger.IsDebugEnabled)
{
  Logger.Debug("message");
}</pre>
<p><strong>2.2 </strong><strong>Repository</strong></p>
<p>Repository主要用于负责日志对象组织结构的维护。在log4net的以前版本中，框架仅支持分等级的组织结构(hierarchical organization)。这种等级结构本质上是库的一个实现，并且定义在log4net.Repository.Hierarchy 名字空间中。要实现一个Repository，需要实现log4net.Repository.ILoggerRepository 接口。但是通常并不是直接实现该接口，而是以log4net.Repository.LoggerRepositorySkeleton为基类继承。体系库 (hierarchical repository )则由log4net.Repository.Hierarchy.Hierarchy类实现。</p>
<p>如果你是个log4net框架的使用者，而非扩展者，那么你几乎不会在你的代码里用到Repository的类。相反的，你需要用到LogManager类来自动管理库和日志对象。</p>
<p><strong>2.3 </strong><strong>Appender</strong></p>
<p>一个好的日志框架应该能够产生多目的地的输出。比如说输出到控制台或保存到一个日志文件。log4net 能够很好的满足这些要求。它使用一个叫做Appender的组件来定义输出介质。正如名字所示，这些组件把它们附加到Logger日志组件上并将输出传递到输出流中。你可以把多个Appender组件附加到一个日志对象上。 Log4net框架提供了几个Appender组件。关于log4net提供的Appender组件的完整列表可以在log4net框架的帮助手册中找到。有了这些现成的Appender组件，一般来说你没有必要再自己编写了。但是如果你愿意，可以从log4net.Appender.AppenderSkeleton类继承。</p>
<p><strong>2.4 </strong><strong>Appender Filters</strong></p>
<p>一个Appender 对象缺省地将所有的日志事件传递到输出流。Appender的过滤器(Appender Filters) 可以按照不同的标准过滤日志事件。在log4net.Filter的名字空间下已经有几个预定义的过滤器。使用这些过滤器，你可以按照日志级别范围过滤日志事件，或者按照某个特殊的字符串进行过滤。你可以在API的帮助文件中发现更多关于过滤器的信息。</p>
<p><strong>2.5 </strong><strong>Layout</strong></p>
<p>Layout 组件用于向用户显示最后经过格式化的输出信息。输出信息可以以多种格式显示，主要依赖于我们采用的Layout组件类型。可以是线性的或一个XML文件。Layout组件和一个Appender组件一起工作。API帮助手册中有关于不同Layout组件的列表。一个Appender对象，只能对应一个Layout对象。要实现你自己的Layout类，你需要从log4net.Layout.LayoutSkeleton类继承，它实现了ILayout接口。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>3 </strong><strong>在程序中使用log4net</strong></p>
<p>在开始对你的程序进行日志记录前，需要先启动log4net引擎。这意味着你需要先配置前面提到的三种组件。你可以用两种方法来设定配置：在单独的文件中设定配置或在代码中定义配置。</p>
<p>因为下面几种原因，推荐在一个单独的文件中定义配置：</p>
<p>l         你不需要重新编译源代码就能改变配置；</p>
<p>l         你可以在程序正运行的时候就改变配置。这一点在一些WEB程序和远程过程调用的程序中有时很重要；</p>
<p>考虑到第一种方法的重要性，我们先看看怎样在文件中设定配置信息。</p>
<p><strong>3.1 </strong><strong>定义配置文件</strong></p>
<p>配置信息可以放在如下几种形式文件的一种中。</p>
<p>在程序的配置文件里，如AssemblyName.config 或web.config.</p>
<p>在你自己的文件里。文件名可以是任何你想要的名字，如AppName.exe.xyz等.</p>
<p>log4net框架会在相对于AppDomain.CurrentDomain.BaseDirectory 属性定义的目录路径下查找配置文件。框架在配置文件里要查找的唯一标识是&lt;log4net&gt;标签。一个完整的配置文件的例子如下：</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />
&lt;configuration&gt;<br />
  &lt;configSections&gt;<br />
    &lt;section name="log4net"<br />
      type="log4net.Config.Log4NetConfigurationSectionHandler,<br />
            log4net-net-1.0"<br />
    /&gt;<br />
  &lt;/configSections&gt;</p>
<p>  &lt;log4net&gt;</p>
<p>    &lt;root&gt;<br />
      &lt;level value="WARN" /&gt;<br />
      &lt;appender-ref ref="LogFileAppender" /&gt;<br />
      &lt;appender-ref ref="ConsoleAppender" /&gt;<br />
    &lt;/root&gt;</p>
<p>    &lt;logger name="testApp.Logging"&gt;<br />
      &lt;level value="DEBUG"/&gt;<br />
    &lt;/logger&gt;</p>
<p>    &lt;appender name="LogFileAppender"<br />
             type="log4net.Appender.FileAppender" &gt;<br />
      &lt;param name="File" value="log-file.txt" /&gt;<br />
      &lt;param name="AppendToFile" value="true" /&gt;</p>
<p>      &lt;layout type="log4net.Layout.PatternLayout"&gt;<br />
        &lt;param name="Header" value="[Header]\r\n"/&gt;<br />
        &lt;param name="Footer" value="[Footer]\r\n"/&gt;<br />
%0</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fmicrosoft_tech%2Fcsharp_develop%2Flog4net_shi_yong_zhi_nan&title=Log4Net%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/microsoft_tech/csharp_develop/log4net_shi_yong_zhi_nan/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>由浅入深认识CIL的基本构成+CIL操作码速记表+CIL操作码大全速查（二）</title>
		<link>http://www.topzs.com/tech-box/you_qian_ru_shen_ren_shi_cil_de_ji_ben_gou_cheng_cil_cao_zuo_ma_su_ji_biao_cil_cao_zuo_ma_da_quan_su_cha_er</link>
		<comments>http://www.topzs.com/tech-box/you_qian_ru_shen_ren_shi_cil_de_ji_ben_gou_cheng_cil_cao_zuo_ma_su_ji_biao_cil_cao_zuo_ma_da_quan_su_cha_er#comments</comments>
		<pubDate>Sun, 03 Jul 2011 00:40:50 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>

		<guid isPermaLink="false">http://www.topzs.com/?p=989</guid>
		<description><![CDATA[一、CIL的基本构成 CIL由CIL指令(directive)、CIL特性(attribute)、CIL操作码(opcode)组成。 CIL指令 CIL指令是用于描述.NET程序集总体结构的标记，并且通知CIL编译器如何定义在程序集中用到的命名空间、类、成员的。它以（.）一个点号开头，例如：.namespace、.class、.property、.method等构成。 CIL特性 CIL特性是由于CIL指令并不能完全说明.NET成员和类的情况下，针对CIL指令进行补充说明成员或者类的特性的。比如一个类可能是公共的，集成的。它就需要用public特性、extends特性或者implements特性对类的.class指令进行修饰的补充说明。 CIL操作码 CIL操作码是对于类或者方法的内部逻辑进行描述和操作的代码，例如Add(将两个值相加并将结果推送到计算堆栈上)、Ldarg(将参数（由指定索引值引用）加载到堆栈上)Ldloc.0(将索引 0 处的局部变量加载到计算堆栈上)等其主要分为以下五大类操作：（数据）的压栈(ld)、弹出(st)、运算、转移、其他、 二、CIL操作码速记表 通过下面的速记表我们可以很容易的记忆CIL的指令：比如我们知道一个ldloc.0=ld(load)+loc(local)+.0(0位置的参数)=将索引 0 处的局部变量加载到计算堆栈上。 主要操作 操作数范围/条件 操作数类型 操作数 缩写 全称 含义 缩写 全称 含义 缩写 全称 含义 缩写 全称 含义 ld load 将操作数压到堆栈当中，相当于： push ax arg argument 参数 ? ? 操作数中的数值 .0 ? 第零个参数 * .1 ? 第一个参数 .2 ? 第二个参数 .3 ? 第三个参数 .s [...]]]></description>
			<content:encoded><![CDATA[<p>一、CIL的基本构成</p>
<p>CIL由CIL指令(directive)、CIL特性(attribute)、CIL操作码(opcode)组成。</p>
<p>CIL指令</p>
<p>CIL指令是用于描述.NET程序集总体结构的标记，并且通知CIL编译器如何定义在程序集中用到的命名空间、类、成员的。它以（.）一个点号开头，例如：.namespace、.class、.property、.method等构成。</p>
<p>CIL特性</p>
<p>CIL特性是由于CIL指令并不能完全说明.NET成员和类的情况下，针对CIL指令进行补充说明成员或者类的特性的。比如一个类可能是公共的，集成的。它就需要用public特性、extends特性或者implements特性对类的.class指令进行修饰的补充说明。</p>
<p>CIL操作码</p>
<p>CIL操作码是对于类或者方法的内部逻辑进行描述和操作的代码，例如Add(将两个值相加并将结果推送到计算堆栈上)、Ldarg(将参数（由指定索引值引用）加载到堆栈上)Ldloc.0(将索引 0 处的局部变量加载到计算堆栈上)等其主要分为以下五大类操作：（数据）的压栈(ld)、弹出(st)、运算、转移、其他、</p>
<p>二、CIL操作码速记表</p>
<p>通过下面的速记表我们可以很容易的记忆CIL的指令：比如我们知道一个ldloc.0=ld(load)+loc(local)+.0(0位置的参数)=将索引 0 处的局部变量加载到计算堆栈上。</p>
<table border="1" cellspacing="0" cellpadding="1" width="101%" height="13">
<tbody>
<tr>
<td colspan="4" width="25%" height="13" align="center">主要操作</td>
<td colspan="3" width="25%" height="13" align="center">操作数范围/条件</td>
<td colspan="3" width="25%" height="13" align="center">操作数类型</td>
<td colspan="3" width="25%" height="13" align="center">操作数</td>
</tr>
<tr>
<td width="4%" height="13" align="center">缩写</td>
<td width="7%" height="13" align="center">全称</td>
<td colspan="2" width="14%" height="13" align="center">含义</td>
<td width="4%" height="13" align="center">缩写</td>
<td width="7%" height="13" align="center">全称</td>
<td width="14%" height="13" align="center">含义</td>
<td width="4%" height="13" align="center">缩写</td>
<td width="7%" height="13" align="center">全称</td>
<td width="14%" height="13" align="center">含义</td>
<td width="4%" height="13" align="center">缩写</td>
<td width="7%" height="13" align="center">全称</td>
<td width="14%" height="13" align="center">含义</td>
</tr>
<tr>
<td rowspan="19" width="4%" height="13" align="center">ld</td>
<td rowspan="19" width="7%" height="13" align="center">load</td>
<td colspan="2" rowspan="19" width="14%" height="13" align="center">将操作数压到堆栈当中，相当于：<br />
push ax</td>
<td rowspan="6" width="4%" height="4" align="center">arg</td>
<td rowspan="6" width="7%" height="4" align="center">argument</td>
<td rowspan="6" width="14%" height="4" align="center">参数</td>
<td rowspan="5" width="4%" height="2" align="center">?</td>
<td rowspan="5" width="7%" height="2" align="center">?</td>
<td rowspan="5" width="14%" height="2" align="center">操作数中的数值</td>
<td width="4%" height="1" align="center">.0</td>
<td width="7%" height="1" align="center">?</td>
<td width="14%" height="1" align="center">第零个参数 *</td>
</tr>
<tr>
<td width="4%" height="1" align="center">.1</td>
<td width="7%" height="1" align="center">?</td>
<td width="14%" height="1" align="center">第一个参数</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.2</td>
<td width="7%" height="0" align="center">?</td>
<td width="14%" height="0" align="center">第二个参数</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.3</td>
<td width="7%" height="0" align="center">?</td>
<td width="14%" height="0" align="center">第三个参数</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.s xx</td>
<td width="7%" height="0" align="center">(short)</td>
<td width="14%" height="0" align="center">参数xx</td>
</tr>
<tr>
<td width="4%" height="1" align="center">a</td>
<td width="7%" height="1" align="center">address</td>
<td width="14%" height="1" align="center">操作数的地址</td>
<td colspan="3" width="25%" height="1" align="center">只有 .s xx，参见ldarg.s</td>
</tr>
<tr>
<td width="4%" height="3" align="center">loc</td>
<td width="7%" height="3" align="center">local</td>
<td width="14%" height="3" align="center">局部变量</td>
<td colspan="6" width="50%" height="3" align="center">参见ldarg</td>
</tr>
<tr>
<td width="4%" height="3" align="center">fld</td>
<td width="7%" height="3" align="center">field</td>
<td width="14%" height="3" align="center">字段（类的全局变量）</td>
<td colspan="3" width="25%" height="3" align="center">参见ldarg</td>
<td width="4%" height="3" align="center">xx</td>
<td width="7%" height="3" align="center">?</td>
<td width="14%" height="3" align="center">xx字段，eg:<br />
ldfld xx</td>
</tr>
<tr>
<td rowspan="10" width="4%" height="2" align="center">c</td>
<td rowspan="10" width="7%" height="2" align="center">const</td>
<td rowspan="10" width="14%" height="2" align="center">常量</td>
<td rowspan="7" width="4%" height="1" align="center">.i4</td>
<td rowspan="7" width="7%" height="1" align="center">int 4 bytes</td>
<td rowspan="7" width="14%" height="1" align="center">C#里面的int，其他的类型例如short需要通过conv转换</td>
<td width="4%" height="1" align="center">.m1</td>
<td width="7%" height="1" align="center">minus 1</td>
<td width="14%" height="1" align="center">-1</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.0</td>
<td width="7%" height="0" align="center">?</td>
<td width="14%" height="0" align="center">0</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.1</td>
<td width="7%" height="0" align="center">?</td>
<td width="14%" height="0" align="center">1</td>
</tr>
<tr>
<td colspan="3" width="25%" height="0" align="center">……</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.8</td>
<td width="14%" height="0" align="center">8</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.s</td>
<td width="7%" height="0" align="center">(short)</td>
<td width="14%" height="0" align="center">后面跟一个字节以内的整型数值（有符号的）</td>
</tr>
<tr>
<td width="4%" height="0" align="center">?</td>
<td width="7%" height="0" align="center">?</td>
<td width="14%" height="0" align="center">后面跟四个字节的整型数值</td>
</tr>
<tr>
<td width="4%" height="1" align="center">.i8</td>
<td width="7%" height="1" align="center">int 8 bytes</td>
<td width="14%" height="1" align="center">C#里面的long</td>
<td width="4%" height="1" align="center">?</td>
<td width="7%" height="1" align="center">?</td>
<td width="14%" height="1" align="center">后面跟八个字节的整型数值</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.r4</td>
<td width="7%" height="0" align="center">real 4 bytes</td>
<td width="14%" height="0" align="center">C#里面的float</td>
<td width="4%" height="0" align="center">?</td>
<td width="7%" height="0" align="center">?</td>
<td width="14%" height="0" align="center">后面跟四个字节的浮点数值</td>
</tr>
<tr>
<td width="4%" height="0" align="center">.r8</td>
<td width="7%" height="0" align="center">real 8 bytes</td>
<td width="14%" height="0" align="center">C#里面的double</td>
<td width="4%" height="0" align="center">?</td>
<td width="7%" height="0" align="center">?</td>
<td width="14%" height="0" align="center">后面跟八个字节的浮点数值</td>
</tr>
<tr>
<td width="4%" height="2" align="center">null</td>
<td width="7%" height="2" align="center">null</td>
<td width="14%" height="2" align="center">空值（也就是0）</td>
<td width="4%" height="2" align="center">?</td>
<td width="7%" height="2" align="center">?</td>
<td width="14%" height="2" align="center">?</td>
<td width="4%" height="2" align="center">?</td>
<td width="7%" height="2" align="center">?</td>
<td width="14%" height="2" align="center">?</td>
</tr>
<tr>
<td width="4%" height="13" align="center">st</td>
<td width="7%" height="13" align="center">store</td>
<td colspan="2" width="14%" height="13" align="center">将堆栈内容弹出到操作数中，相当于：<br />
pop ax</td>
<td colspan="9" width="75%" height="13" align="center">参见ld **</td>
</tr>
<tr>
<td rowspan="8" width="4%" height="13" align="center">conv</td>
<td rowspan="8" width="7%" height="13" align="center">convert</td>
<td colspan="2" rowspan="8" width="14%" height="13" align="center">数值类型转换，仅仅用纯粹的数值类型间的转换，例如int/float等</td>
<td rowspan="8" width="4%" height="13" align="center">?</td>
<td rowspan="8" width="7%" height="13" align="center">?</td>
<td rowspan="8" width="14%" height="13" align="center">?</td>
<td width="4%" height="2" align="center">.i1</td>
<td width="7%" height="2" align="center">int 1 bytes</td>
<td width="14%" height="2" align="center">C#里面的sbyte</td>
<td rowspan="8" width="4%" height="13" align="center">?</td>
<td rowspan="8" width="7%" height="13" align="center">?</td>
<td rowspan="8" width="14%" height="13" align="center">?</td>
</tr>
<tr>
<td width="4%" height="2" align="center">.i2</td>
<td width="7%" height="2" align="center">int 2 bytes</td>
<td width="14%" height="2" align="center">C#里面的short</td>
</tr>
<tr>
<td width="4%" height="2" align="center">.i4</td>
<td width="7%" height="2" align="center">int 4 bytes</td>
<td width="14%" height="2" align="center">C#里面的int</td>
</tr>
<tr>
<td width="4%" height="2" align="center">.i8</td>
<td width="7%" height="2" align="center">int 8 bytes</td>
<td width="14%" height="2" align="center">C#里面的long</td>
</tr>
<tr>
<td width="4%" height="2" align="center">.r4</td>
<td width="7%" height="2" align="center">real 4 bytes</td>
<td width="14%" height="2" align="center">C#里面的float</td>
</tr>
<tr>
<td width="4%" height="1" align="center">.r8</td>
<td width="7%" height="1" align="center">real 8 bytes</td>
<td width="14%" height="1" align="center">C#里面的double</td>
</tr>
<tr>
<td width="4%" height="1" align="center">.u4</td>
<td width="7%" height="1" align="center">uint 4 bytes</td>
<td width="14%" height="1" align="center">C#里面的uint</td>
</tr>
<tr>
<td width="4%" height="1" align="center">.u8</td>
<td width="7%" height="1" align="center">uint 8 bytes</td>
<td width="14%" height="1" align="center">C#里面的ulong</td>
</tr>
<tr>
<td rowspan="10" width="4%" height="13" align="center">b/br</td>
<td rowspan="10" width="7%" height="13" align="center">branch</td>
<td rowspan="10" width="12%" height="13" align="center">条件和无条件跳转，相当于：<br />
jmp/jxx label_jump</td>
<td rowspan="4" width="3%" height="6" align="center">br</td>
<td rowspan="2" width="4%" height="2" align="center">?</td>
<td rowspan="2" width="7%" height="2" align="center">?</td>
<td rowspan="2" width="14%" height="2" align="center">无条件跳转</td>
<td rowspan="2" width="4%" height="2" align="center">?</td>
<td rowspan="2" width="7%" height="2" align="center">?</td>
<td rowspan="2" width="14%" height="2" align="center">?</td>
<td width="4%" height="1" align="center">?</td>
<td width="7%" height="1" align="center">?</td>
<td width="14%" height="1" align="center">后面跟四个字节的偏移量（有符号）</td>
</tr>
<tr>
<td width="4%" height="1" align="center">.s</td>
<td width="7%" height="1" align="center">(short)</td>
<td width="14%" height="1" align="center">后面跟一个字节的偏移量（有符号）</td>
</tr>
<tr>
<td width="4%" height="2" align="center">false</td>
<td width="7%" height="2" align="center">false</td>
<td width="14%" height="2" align="center">值为零的时候跳转</td>
<td width="4%" height="2" align="center">?</td>
<td width="7%" height="2" align="center">?</td>
<td width="14%" height="2" align="center">?</td>
<td colspan="3" rowspan="8" width="25%" height="11" align="center">参见br</td>
</tr>
<tr>
<td width="4%" height="2" align="center">true</td>
<td width="7%" height="2" align="center">true</td>
<td width="14%" height="2" align="center">值不为零的时候跳转</td>
<td width="4%" height="2" align="center">?</td>
<td width="7%" height="2" align="center">?</td>
<td width="14%" height="2" align="center">?</td>
</tr>
<tr>
<td rowspan="6" width="3%" height="7" align="center">b</td>
<td width="4%" height="2" align="center">eq</td>
<td width="7%" height="2" align="center">equal to</td>
<td width="14%" height="2" align="center">相等</td>
<td width="4%" height="2" align="center">?</td>
<td width="7%" height="2" align="center">?</td>
<td width="14%" height="2" align="center">?</td>
</tr>
<tr>
<td width="4%" height="1" align="center">ne</td>
<td width="7%" height="1" align="center">not equal to</td>
<td width="14%" height="1" align="center">不相等</td>
<td rowspan="5" width="4%" height="5" align="center">un</td>
<td rowspan="5" width="7%" height="5" align="center">unsigned or unordered</td>
<td rowspan="5" width="14%" height="5" align="center">无氟好的（对于整数）或者无序的（对于浮点）</td>
</tr>
<tr>
<td width="4%" height="1" align="center">gt</td>
<td width="7%" height="1" align="center">greater than</td>
<td width="14%" height="1" align="center">大于</td>
</tr>
<tr>
<td width="4%" height="1" align="center">lt</td>
<td width="7%" height="1" align="center">less than</td>
<td width="14%" height="1" align="center">小于</td>
</tr>
<tr>
<td width="4%" height="1" align="center">ge</td>
<td width="7%" height="1" align="center">greater than or equal to</td>
<td width="14%" height="1" align="center">大于等于</td>
</tr>
<tr>
<td width="4%" height="1" align="center">le</td>
<td width="7%" height="1" align="center">less than or equal to</td>
<td width="14%" height="1" align="center">小于等于</td>
</tr>
<tr>
<td rowspan="2" width="4%" height="13" align="center">call</td>
<td rowspan="2" width="7%" height="13" align="center">call</td>
<td colspan="2" rowspan="2" width="14%" height="13" align="center">调用</td>
<td width="4%" height="7" align="center">?</td>
<td width="7%" height="7" align="center">?</td>
<td width="14%" height="7" align="center">?</td>
<td width="4%" height="7" align="center">?</td>
<td width="7%" height="7" align="center">?</td>
<td width="14%" height="7" align="center">（非虚函数）</td>
<td colspan="3" rowspan="2" width="25%" height="14" align="center">?</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong>三、CIL操作码大全速查</strong></p>
<p>通过下面的速查大全即可快速的查找CIL指令的作用。</p>
<table border="0" cellspacing="0" cellpadding="0" width="1029">
<tbody>
<tr>
<td width="114" align="center">名称</td>
<td width="913" align="center">说明</td>
</tr>
<tr>
<td>Add</td>
<td width="913">将两个值相加并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Add.Ovf</td>
<td width="913">将两个整数相加，执行溢出检查，并且将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Add.Ovf.Un</td>
<td width="913">将两个无符号整数值相加，执行溢出检查，并且将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>And</td>
<td width="913">计算两个值的按位“与”并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Arglist</td>
<td width="913">返回指向当前方法的参数列表的非托管指针。</td>
</tr>
<tr>
<td>Beq</td>
<td width="913">如果两个值相等，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Beq.S</td>
<td width="913">如果两个值相等，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Bge</td>
<td width="913">如果第一个值大于或等于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Bge.S</td>
<td width="913">如果第一个值大于或等于第二个值，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Bge.Un</td>
<td width="913">当比较无符号整数值或不可排序的浮点型值时，如果第一个值大于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Bge.Un.S</td>
<td width="913">当比较无符号整数值或不可排序的浮点型值时，如果第一个值大于第二个值，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Bgt</td>
<td width="913">如果第一个值大于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Bgt.S</td>
<td width="913">如果第一个值大于第二个值，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Bgt.Un</td>
<td width="913">当比较无符号整数值或不可排序的浮点型值时，如果第一个值大于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Bgt.Un.S</td>
<td width="913">当比较无符号整数值或不可排序的浮点型值时，如果第一个值大于第二个值，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Ble</td>
<td width="913">如果第一个值小于或等于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Ble.S</td>
<td width="913">如果第一个值小于或等于第二个值，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Ble.Un</td>
<td width="913">当比较无符号整数值或不可排序的浮点型值时，如果第一个值小于或等于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Ble.Un.S</td>
<td width="913">当比较无符号整数值或不可排序的浮点值时，如果第一个值小于或等于第二个值，则将控制权转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Blt</td>
<td width="913">如果第一个值小于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Blt.S</td>
<td width="913">如果第一个值小于第二个值，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Blt.Un</td>
<td width="913">当比较无符号整数值或不可排序的浮点型值时，如果第一个值小于第二个值，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Blt.Un.S</td>
<td width="913">当比较无符号整数值或不可排序的浮点型值时，如果第一个值小于第二个值，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Bne.Un</td>
<td width="913">当两个无符号整数值或不可排序的浮点型值不相等时，将控制转移到目标指令。</td>
</tr>
<tr>
<td>Bne.Un.S</td>
<td width="913">当两个无符号整数值或不可排序的浮点型值不相等时，将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Box</td>
<td width="913">将值类转换为对象引用（O 类型）。</td>
</tr>
<tr>
<td>Br</td>
<td width="913">无条件地将控制转移到目标指令。</td>
</tr>
<tr>
<td>Br.S</td>
<td width="913">无条件地将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Break</td>
<td width="913">向公共语言结构 (CLI) 发出信号以通知调试器已撞上了一个断点。</td>
</tr>
<tr>
<td>Brfalse</td>
<td width="913">如果 value 为 false、空引用（Visual Basic 中的 Nothing）或零，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Brfalse.S</td>
<td width="913">如果 value 为 false、空引用或零，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Brtrue</td>
<td width="913">如果 value 为 true、非空或非零，则将控制转移到目标指令。</td>
</tr>
<tr>
<td>Brtrue.S</td>
<td width="913">如果 value 为 true、非空或非零，则将控制转移到目标指令（短格式）。</td>
</tr>
<tr>
<td>Call</td>
<td width="913">调用由传递的方法说明符指示的方法。</td>
</tr>
<tr>
<td>Calli</td>
<td width="913">通过调用约定描述的参数调用在计算堆栈上指示的方法（作为指向入口点的指针）。</td>
</tr>
<tr>
<td>Callvirt</td>
<td width="913">对对象调用后期绑定方法，并且将返回值推送到计算堆栈上。</td>
</tr>
<tr>
<td>Castclass</td>
<td width="913">尝试将引用传递的对象转换为指定的类。</td>
</tr>
<tr>
<td>Ceq</td>
<td width="913">比较两个值。如果这两个值相等，则将整数值 1 (int32) 推送到计算堆栈上；否则，将 0 (int32) 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Cgt</td>
<td width="913">比较两个值。如果第一个值大于第二个值，则将整数值 1 (int32) 推送到计算堆栈上；反之，将 0 (int32) 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Cgt.Un</td>
<td width="913">比较两个无符号的或不可排序的值。如果第一个值大于第二个值，则将整数值 1 (int32) 推送到计算堆栈上；反之，将 0 (int32) 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ckfinite</td>
<td width="913">如果值不是有限数，则引发 ArithmeticException。</td>
</tr>
<tr>
<td>Clt</td>
<td width="913">比较两个值。如果第一个值小于第二个值，则将整数值 1 (int32) 推送到计算堆栈上；反之，将 0 (int32) 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Clt.Un</td>
<td width="913">比较无符号的或不可排序的值 value1 和 value2。如果 value1 小于 value2，则将整数值 1 (int32 ) 推送到计算堆栈上；反之，将 0 ( int32 ) 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Constrained</td>
<td width="913">约束要对其进行虚方法调用的类型。</td>
</tr>
<tr>
<td>Conv.I</td>
<td width="913">将位于计算堆栈顶部的值转换为 native int。</td>
</tr>
<tr>
<td>Conv.I1</td>
<td width="913">将位于计算堆栈顶部的值转换为 int8，然后将其扩展（填充）为 int32。</td>
</tr>
<tr>
<td>Conv.I2</td>
<td width="913">将位于计算堆栈顶部的值转换为 int16，然后将其扩展（填充）为 int32。</td>
</tr>
<tr>
<td>Conv.I4</td>
<td width="913">将位于计算堆栈顶部的值转换为 int32。</td>
</tr>
<tr>
<td>Conv.I8</td>
<td width="913">将位于计算堆栈顶部的值转换为 int64。</td>
</tr>
<tr>
<td>Conv.Ovf.I</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为有符号 native int，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为有符号 native int，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I1</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为有符号 int8 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I1.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为有符号 int8 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I2</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为有符号 int16 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I2.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为有符号 int16 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I4</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为有符号 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I4.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为有符号 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I8</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为有符号 int64，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.I8.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为有符号 int64，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为 unsigned native int，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为 unsigned native int，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U1</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为 unsigned int8 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U1.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为 unsigned int8 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U2</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为 unsigned int16 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U2.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为 unsigned int16 并将其扩展为 int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U4</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为 unsigned int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U4.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为 unsigned int32，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U8</td>
<td width="913">将位于计算堆栈顶部的有符号值转换为 unsigned int64，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.Ovf.U8.Un</td>
<td width="913">将位于计算堆栈顶部的无符号值转换为 unsigned int64，并在溢出时引发 OverflowException。</td>
</tr>
<tr>
<td>Conv.R.Un</td>
<td width="913">将位于计算堆栈顶部的无符号整数值转换为 float32。</td>
</tr>
<tr>
<td>Conv.R4</td>
<td width="913">将位于计算堆栈顶部的值转换为 float32。</td>
</tr>
<tr>
<td>Conv.R8</td>
<td width="913">将位于计算堆栈顶部的值转换为 float64。</td>
</tr>
<tr>
<td>Conv.U</td>
<td width="913">将位于计算堆栈顶部的值转换为 unsigned native int，然后将其扩展为 native int。</td>
</tr>
<tr>
<td>Conv.U1</td>
<td width="913">将位于计算堆栈顶部的值转换为 unsigned int8，然后将其扩展为 int32。</td>
</tr>
<tr>
<td>Conv.U2</td>
<td width="913">将位于计算堆栈顶部的值转换为 unsigned int16，然后将其扩展为 int32。</td>
</tr>
<tr>
<td>Conv.U4</td>
<td width="913">将位于计算堆栈顶部的值转换为 unsigned int32，然后将其扩展为 int32。</td>
</tr>
<tr>
<td>Conv.U8</td>
<td width="913">将位于计算堆栈顶部的值转换为 unsigned int64，然后将其扩展为 int64。</td>
</tr>
<tr>
<td>Cpblk</td>
<td width="913">将指定数目的字节从源地址复制到目标地址。</td>
</tr>
<tr>
<td>Cpobj</td>
<td width="913">将位于对象（&amp;、* 或 native int 类型）地址的值类型复制到目标对象（&amp;、* 或 native int 类型）的地址。</td>
</tr>
<tr>
<td>Div</td>
<td width="913">将两个值相除并将结果作为浮点（F 类型）或商（int32 类型）推送到计算堆栈上。</td>
</tr>
<tr>
<td>Div.Un</td>
<td width="913">两个无符号整数值相除并将结果 ( int32 ) 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Dup</td>
<td width="913">复制计算堆栈上当前最顶端的值，然后将副本推送到计算堆栈上。</td>
</tr>
<tr>
<td>Endfilter</td>
<td width="913">将控制从异常的 filter 子句转移回公共语言结构 (CLI) 异常处理程序。</td>
</tr>
<tr>
<td>Endfinally</td>
<td width="913">将控制从异常块的 fault 或 finally 子句转移回公共语言结构 (CLI) 异常处理程序。</td>
</tr>
<tr>
<td>Initblk</td>
<td width="913">将位于特定地址的内存的指定块初始化为给定大小和初始值。</td>
</tr>
<tr>
<td>Initobj</td>
<td width="913">将位于指定地址的值类型的每个字段初始化为空引用或适当的基元类型的 0。</td>
</tr>
<tr>
<td>Isinst</td>
<td width="913">测试对象引用（O 类型）是否为特定类的实例。</td>
</tr>
<tr>
<td>Jmp</td>
<td width="913">退出当前方法并跳至指定方法。</td>
</tr>
<tr>
<td>Ldarg</td>
<td width="913">将参数（由指定索引值引用）加载到堆栈上。</td>
</tr>
<tr>
<td>Ldarg.0</td>
<td width="913">将索引为 0 的参数加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldarg.1</td>
<td width="913">将索引为 1 的参数加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldarg.2</td>
<td width="913">将索引为 2 的参数加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldarg.3</td>
<td width="913">将索引为 3 的参数加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldarg.S</td>
<td width="913">将参数（由指定的短格式索引引用）加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldarga</td>
<td width="913">将参数地址加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldarga.S</td>
<td width="913">以短格式将参数地址加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4</td>
<td width="913">将所提供的 int32 类型的值作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.0</td>
<td width="913">将整数值 0 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.1</td>
<td width="913">将整数值 1 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.2</td>
<td width="913">将整数值 2 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.3</td>
<td width="913">将整数值 3 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.4</td>
<td width="913">将整数值 4 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.5</td>
<td width="913">将整数值 5 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.6</td>
<td width="913">将整数值 6 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.7</td>
<td width="913">将整数值 7 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.8</td>
<td width="913">将整数值 8 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.M1</td>
<td width="913">将整数值 -1 作为 int32 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.I4.S</td>
<td width="913">将提供的 int8 值作为 int32 推送到计算堆栈上（短格式）。</td>
</tr>
<tr>
<td>Ldc.I8</td>
<td width="913">将所提供的 int64 类型的值作为 int64 推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.R4</td>
<td width="913">将所提供的 float32 类型的值作为 F (float) 类型推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldc.R8</td>
<td width="913">将所提供的 float64 类型的值作为 F (float) 类型推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldelem</td>
<td width="913">按照指令中指定的类型，将指定数组索引中的元素加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.I</td>
<td width="913">将位于指定数组索引处的 native int 类型的元素作为 native int 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.I1</td>
<td width="913">将位于指定数组索引处的 int8 类型的元素作为 int32 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.I2</td>
<td width="913">将位于指定数组索引处的 int16 类型的元素作为 int32 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.I4</td>
<td width="913">将位于指定数组索引处的 int32 类型的元素作为 int32 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.I8</td>
<td width="913">将位于指定数组索引处的 int64 类型的元素作为 int64 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.R4</td>
<td width="913">将位于指定数组索引处的 float32 类型的元素作为 F 类型（浮点型）加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.R8</td>
<td width="913">将位于指定数组索引处的 float64 类型的元素作为 F 类型（浮点型）加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.Ref</td>
<td width="913">将位于指定数组索引处的包含对象引用的元素作为 O 类型（对象引用）加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.U1</td>
<td width="913">将位于指定数组索引处的 unsigned int8 类型的元素作为 int32 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.U2</td>
<td width="913">将位于指定数组索引处的 unsigned int16 类型的元素作为 int32 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelem.U4</td>
<td width="913">将位于指定数组索引处的 unsigned int32 类型的元素作为 int32 加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldelema</td>
<td width="913">将位于指定数组索引的数组元素的地址作为 &amp; 类型（托管指针）加载到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldfld</td>
<td width="913">查找对象中其引用当前位于计算堆栈的字段的值。</td>
</tr>
<tr>
<td>Ldflda</td>
<td width="913">查找对象中其引用当前位于计算堆栈的字段的地址。</td>
</tr>
<tr>
<td>Ldftn</td>
<td width="913">将指向实现特定方法的本机代码的非托管指针（native int 类型）推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.I</td>
<td width="913">将 native int 类型的值作为 native int 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.I1</td>
<td width="913">将 int8 类型的值作为 int32 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.I2</td>
<td width="913">将 int16 类型的值作为 int32 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.I4</td>
<td width="913">将 int32 类型的值作为 int32 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.I8</td>
<td width="913">将 int64 类型的值作为 int64 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.R4</td>
<td width="913">将 float32 类型的值作为 F (float) 类型间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.R8</td>
<td width="913">将 float64 类型的值作为 F (float) 类型间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.Ref</td>
<td width="913">将对象引用作为 O（对象引用）类型间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.U1</td>
<td width="913">将 unsigned int8 类型的值作为 int32 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.U2</td>
<td width="913">将 unsigned int16 类型的值作为 int32 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldind.U4</td>
<td width="913">将 unsigned int32 类型的值作为 int32 间接加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldlen</td>
<td width="913">将从零开始的、一维数组的元素的数目推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldloc</td>
<td width="913">将指定索引处的局部变量加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldloc.0</td>
<td width="913">将索引 0 处的局部变量加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldloc.1</td>
<td width="913">将索引 1 处的局部变量加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldloc.2</td>
<td width="913">将索引 2 处的局部变量加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldloc.3</td>
<td width="913">将索引 3 处的局部变量加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldloc.S</td>
<td width="913">将特定索引处的局部变量加载到计算堆栈上（短格式）。</td>
</tr>
<tr>
<td>Ldloca</td>
<td width="913">将位于特定索引处的局部变量的地址加载到计算堆栈上。</td>
</tr>
<tr>
<td>Ldloca.S</td>
<td width="913">将位于特定索引处的局部变量的地址加载到计算堆栈上（短格式）。</td>
</tr>
<tr>
<td>Ldnull</td>
<td width="913">将空引用（O 类型）推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldobj</td>
<td width="913">将地址指向的值类型对象复制到计算堆栈的顶部。</td>
</tr>
<tr>
<td>Ldsfld</td>
<td width="913">将静态字段的值推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldsflda</td>
<td width="913">将静态字段的地址推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldstr</td>
<td width="913">推送对元数据中存储的字符串的新对象引用。</td>
</tr>
<tr>
<td>Ldtoken</td>
<td width="913">将元数据标记转换为其运行时表示形式，并将其推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ldvirtftn</td>
<td width="913">将指向实现与指定对象关联的特定虚方法的本机代码的非托管指针（native int 类型）推送到计算堆栈上。</td>
</tr>
<tr>
<td>Leave</td>
<td width="913">退出受保护的代码区域，无条件将控制转移到特定目标指令。</td>
</tr>
<tr>
<td>Leave.S</td>
<td width="913">退出受保护的代码区域，无条件将控制转移到目标指令（缩写形式）。</td>
</tr>
<tr>
<td>Localloc</td>
<td width="913">从本地动态内存池分配特定数目的字节并将第一个分配的字节的地址（瞬态指针，* 类型）推送到计算堆栈上。</td>
</tr>
<tr>
<td>Mkrefany</td>
<td width="913">将对特定类型实例的类型化引用推送到计算堆栈上。</td>
</tr>
<tr>
<td>Mul</td>
<td width="913">将两个值相乘并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Mul.Ovf</td>
<td width="913">将两个整数值相乘，执行溢出检查，并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Mul.Ovf.Un</td>
<td width="913">将两个无符号整数值相乘，执行溢出检查，并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Neg</td>
<td width="913">对一个值执行求反并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Newarr</td>
<td width="913">将对新的从零开始的一维数组（其元素属于特定类型）的对象引用推送到计算堆栈上。</td>
</tr>
<tr>
<td>Newobj</td>
<td width="913">创建一个值类型的新对象或新实例，并将对象引用（O 类型）推送到计算堆栈上。</td>
</tr>
<tr>
<td>Nop</td>
<td width="913">如果修补操作码，则填充空间。尽管可能消耗处理周期，但未执行任何有意义的操作。</td>
</tr>
<tr>
<td>Not</td>
<td width="913">计算堆栈顶部整数值的按位求补并将结果作为相同的类型推送到计算堆栈上。</td>
</tr>
<tr>
<td>Or</td>
<td width="913">计算位于堆栈顶部的两个整数值的按位求补并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Pop</td>
<td width="913">移除当前位于计算堆栈顶部的值。</td>
</tr>
<tr>
<td>Prefix1</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Prefix2</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Prefix3</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Prefix4</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Prefix5</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Prefix6</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Prefix7</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Prefixref</td>
<td width="913">基础结构。此指令为保留指令。</td>
</tr>
<tr>
<td>Readonly</td>
<td width="913">指定后面的数组地址操作在运行时不执行类型检查，并且返回可变性受限的托管指针。</td>
</tr>
<tr>
<td>Refanytype</td>
<td width="913">检索嵌入在类型化引用内的类型标记。</td>
</tr>
<tr>
<td>Refanyval</td>
<td width="913">检索嵌入在类型化引用内的地址（&amp; 类型）。</td>
</tr>
<tr>
<td>Rem</td>
<td width="913">将两个值相除并将余数推送到计算堆栈上。</td>
</tr>
<tr>
<td>Rem.Un</td>
<td width="913">将两个无符号值相除并将余数推送到计算堆栈上。</td>
</tr>
<tr>
<td>Ret</td>
<td width="913">从当前方法返回，并将返回值（如果存在）从调用方的计算堆栈推送到被调用方的计算堆栈上。</td>
</tr>
<tr>
<td>Rethrow</td>
<td width="913">再次引发当前异常。</td>
</tr>
<tr>
<td>Shl</td>
<td width="913">将整数值左移（用零填充）指定的位数，并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Shr</td>
<td width="913">将整数值右移（保留符号）指定的位数，并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Shr.Un</td>
<td width="913">将无符号整数值右移（用零填充）指定的位数，并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Sizeof</td>
<td width="913">将提供的值类型的大小（以字节为单位）推送到计算堆栈上。</td>
</tr>
<tr>
<td>Starg</td>
<td width="913">将位于计算堆栈顶部的值存储到位于指定索引的参数槽中。</td>
</tr>
<tr>
<td>Starg.S</td>
<td width="913">将位于计算堆栈顶部的值存储在参数槽中的指定索引处（短格式）。</td>
</tr>
<tr>
<td>Stelem</td>
<td width="913">用计算堆栈中的值替换给定索引处的数组元素，其类型在指令中指定。</td>
</tr>
<tr>
<td>Stelem.I</td>
<td width="913">用计算堆栈上的 native int 值替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stelem.I1</td>
<td width="913">用计算堆栈上的 int8 值替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stelem.I2</td>
<td width="913">用计算堆栈上的 int16 值替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stelem.I4</td>
<td width="913">用计算堆栈上的 int32 值替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stelem.I8</td>
<td width="913">用计算堆栈上的 int64 值替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stelem.R4</td>
<td width="913">用计算堆栈上的 float32 值替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stelem.R8</td>
<td width="913">用计算堆栈上的 float64 值替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stelem.Ref</td>
<td width="913">用计算堆栈上的对象 ref 值（O 类型）替换给定索引处的数组元素。</td>
</tr>
<tr>
<td>Stfld</td>
<td width="913">用新值替换在对象引用或指针的字段中存储的值。</td>
</tr>
<tr>
<td>Stind.I</td>
<td width="913">在所提供的地址存储 native int 类型的值。</td>
</tr>
<tr>
<td>Stind.I1</td>
<td width="913">在所提供的地址存储 int8 类型的值。</td>
</tr>
<tr>
<td>Stind.I2</td>
<td width="913">在所提供的地址存储 int16 类型的值。</td>
</tr>
<tr>
<td>Stind.I4</td>
<td width="913">在所提供的地址存储 int32 类型的值。</td>
</tr>
<tr>
<td>Stind.I8</td>
<td width="913">在所提供的地址存储 int64 类型的值。</td>
</tr>
<tr>
<td>Stind.R4</td>
<td width="913">在所提供的地址存储 float32 类型的值。</td>
</tr>
<tr>
<td>Stind.R8</td>
<td width="913">在所提供的地址存储 float64 类型的值。</td>
</tr>
<tr>
<td>Stind.Ref</td>
<td width="913">存储所提供地址处的对象引用值。</td>
</tr>
<tr>
<td>Stloc</td>
<td width="913">从计算堆栈的顶部弹出当前值并将其存储到指定索引处的局部变量列表中。</td>
</tr>
<tr>
<td>Stloc.0</td>
<td width="913">从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中。</td>
</tr>
<tr>
<td>Stloc.1</td>
<td width="913">从计算堆栈的顶部弹出当前值并将其存储到索引 1 处的局部变量列表中。</td>
</tr>
<tr>
<td>Stloc.2</td>
<td width="913">从计算堆栈的顶部弹出当前值并将其存储到索引 2 处的局部变量列表中。</td>
</tr>
<tr>
<td>Stloc.3</td>
<td width="913">从计算堆栈的顶部弹出当前值并将其存储到索引 3 处的局部变量列表中。</td>
</tr>
<tr>
<td>Stloc.S</td>
<td width="913">从计算堆栈的顶部弹出当前值并将其存储在局部变量列表中的 index 处（短格式）。</td>
</tr>
<tr>
<td>Stobj</td>
<td width="913">将指定类型的值从计算堆栈复制到所提供的内存地址中。</td>
</tr>
<tr>
<td>Stsfld</td>
<td width="913">用来自计算堆栈的值替换静态字段的值。</td>
</tr>
<tr>
<td>Sub</td>
<td width="913">从其他值中减去一个值并将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Sub.Ovf</td>
<td width="913">从另一值中减去一个整数值，执行溢出检查，并且将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Sub.Ovf.Un</td>
<td width="913">从另一值中减去一个无符号整数值，执行溢出检查，并且将结果推送到计算堆栈上。</td>
</tr>
<tr>
<td>Switch</td>
<td width="913">实现跳转表。</td>
</tr>
<tr>
<td>Tailcall</td>
<td width="913">执行后缀的方法调用指令，以便在执行实际调用指令前移除当前方法的堆栈帧。</td>
</tr>
<tr>
<td>Throw</td>
<td width="913">引发当前位于计算堆栈上的异常对象。</td>
</tr>
<tr>
<td>Unaligned</td>
<td width="913">指示当前位于计算堆栈上的地址可能没有与紧接的 ldind、stind、ldfld、stfld、ldobj、stobj、initblk 或 cpblk 指令的自然大小对齐。</td>
</tr>
<tr>
<td>Unbox</td>
<td width="913">将值类型的已装箱的表示形式转换为其未装箱的形式。</td>
</tr>
<tr>
<td>Unbox.Any</td>
<td width="913">将指令中指定类型的已装箱的表示形式转换成未装箱形式。</td>
</tr>
<tr>
<td>Volatile</td>
<td width="913">指定当前位于计算堆栈顶部的地址可以是易失的，并且读取该位置的结果不能被缓存，或者对该地址的多个存储区不能被取消。</td>
</tr>
<tr>
<td>Xor</td>
<td width="913">计算位于计算堆栈顶部的两个值的按位异或，并且将结果推送到计算堆栈上。</td>
</tr>
</tbody>
</table>
<p><strong>参考资料：</strong></p>
<p>飞鸟123的 <a href="http://www.cnblogs.com/flyingbirds123/archive/2011/01/29/1947626.html">.net IL 指令速查</a></p>
<p>(美国)(Andrewtroelsen)特罗尔森的《C#与.NET3.5高级程序设计(第4版)》、</p>
<p>Sumtec的<a href="http://www.cnblogs.com/sumtec/articles/6872.html">CLI里面的秘密……（一）总体介绍，以及CIL.</a></p>
<p>&nbsp;</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fyou_qian_ru_shen_ren_shi_cil_de_ji_ben_gou_cheng_cil_cao_zuo_ma_su_ji_biao_cil_cao_zuo_ma_da_quan_su_cha_er&title=%E7%94%B1%E6%B5%85%E5%85%A5%E6%B7%B1%E8%AE%A4%E8%AF%86CIL%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%9E%84%E6%88%90%2BCIL%E6%93%8D%E4%BD%9C%E7%A0%81%E9%80%9F%E8%AE%B0%E8%A1%A8%2BCIL%E6%93%8D%E4%BD%9C%E7%A0%81%E5%A4%A7%E5%85%A8%E9%80%9F%E6%9F%A5%EF%BC%88%E4%BA%8C%EF%BC%89" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/you_qian_ru_shen_ren_shi_cil_de_ji_ben_gou_cheng_cil_cao_zuo_ma_su_ji_biao_cil_cao_zuo_ma_da_quan_su_cha_er/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>由浅入深认识CIL通用中间语言（一）</title>
		<link>http://www.topzs.com/tech-box/you_qian_ru_shen_ren_shi_cil_tong_yong_zhong_jian_yu_yan_yi</link>
		<comments>http://www.topzs.com/tech-box/you_qian_ru_shen_ren_shi_cil_tong_yong_zhong_jian_yu_yan_yi#comments</comments>
		<pubDate>Wed, 29 Jun 2011 06:33:15 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[CIL]]></category>
		<category><![CDATA[由浅入深]]></category>

		<guid isPermaLink="false">http://www.topzs.com/?p=982</guid>
		<description><![CDATA[CIL简介：CIL（Common Intermediate Language）中文名为通用中间语言，注意它曾经被称为微软中间语言或MSIL，它是一种类似于JAVA字节码的语言。在微软语言平台中，不管程序员使用C#、VB.NET或者J#等语言编写的程序进行编译的时候，编译器将这几种语言编写的源代码编译为CIL（微软中间语言）语言，此时再通过JIL（Just In Time实时编译器）编译为针对各种不同CPU的指令（注意因为是实时的编译器，所以它运行的时候是只运行需要编译的CIL语言段，而不是全部一下编译完，这是为了提高效率。） 了解CIL好处：1.本系列文章用于研究和探讨CIL中间语言，在实际应用中能够让你选择更好的语法，例如：是选择For还是选择Foreach做循环遍历？ 2.深入的了解.NET内存的分配以及底层的语言运行原理。例如：.Net值类型和引用类型的内存分配？ 3.使用System.Reflection.Emit下的Emit加载CIL命令，动态创建类。 初步认识CIL： 一、我们新建一个C#语言编写的控制台程序命名为ConsoleApplication6，然后键入以下代码： namespace ConsoleApplication6 { class Program { static void Main(string[] args) { string a = "Hello World!"; Console.WriteLine(a); } } } 二、很明显上面的语句将会在控制台输出一个字符串“Hello World!”，那么这个控制台程序的CIL语言是怎样的呢？我们下面可以通过VS2010自带的SDK工具IL Disassembler（ILDASM）打开上面应用程序创建的ConsoleApplication6.exe文件，以查看其CIL语言。如下图方式以打开ILDASM工具： 二、很明显上面的语句将会在控制台输出一个字符串“Hello World!”，那么这个控制台程序的CIL语言是怎样的呢？我们下面可以通过VS2010自带的SDK工具IL Disassembler（ILDASM）打开上面应用程序创建的ConsoleApplication6.exe文件，以查看其CIL语言。如下图方式以打开ILDASM工具： 打开ILDASM工具界面如下： 本图代表一个ConsoleApplication6的命名空间下有一个类叫ConsoleApplication6.Program，这个类下面有一个类清单(.class private auto ansi beforefieldinit)+默认构造函数(.ctor:void())+静态函数(Main:void(string[]))。 注意：上图的界面中有一些红色的三角形，或者蓝色的盾形等分别代表更多信息或者是命名空间等信息，其具体含义如下图所示： 三、点击默认构造函数.ctor:void()我们可以看到这个构造函数的CIL语言如下： .method public hidebysig specialname rtspecialname //.method表示对方法 instance void .ctor() cil managed [...]]]></description>
			<content:encoded><![CDATA[<p>CIL简介：CIL（Common Intermediate Language）中文名为通用中间语言，注意它曾经被称为微软中间语言或MSIL，它是一种类似于JAVA字节码的语言。在微软语言平台中，不管程序员使用C#、VB.NET或者J#等语言编写的程序进行编译的时候，编译器将这几种语言编写的源代码编译为CIL（微软中间语言）语言，此时再通过JIL（Just In Time实时编译器）编译为针对各种不同CPU的指令（注意因为是实时的编译器，所以它运行的时候是只运行需要编译的CIL语言段，而不是全部一下编译完，这是为了提高效率。）</p>
<p>了解CIL好处：1.本系列文章用于研究和探讨CIL中间语言，在实际应用中能够让你选择更好的语法，例如：是选择For还是选择Foreach做循环遍历？</p>
<p>2.深入的了解.NET内存的分配以及底层的语言运行原理。例如：.Net值类型和引用类型的内存分配？</p>
<p>3.使用System.Reflection.Emit下的Emit加载CIL命令，动态创建类。</p>
<p>初步认识CIL：</p>
<p>一、我们新建一个C#语言编写的控制台程序命名为ConsoleApplication6，然后键入以下代码：</p>
<pre class="brush:csharp">namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            string a = "Hello World!";
            Console.WriteLine(a);
        }
    }
}</pre>
<p>二、很明显上面的语句将会在控制台输出一个字符串“Hello World!”，那么这个控制台程序的CIL语言是怎样的呢？我们下面可以通过VS2010自带的SDK工具IL Disassembler（ILDASM）打开上面应用程序创建的ConsoleApplication6.exe文件，以查看其CIL语言。如下图方式以打开ILDASM工具：</p>
<p>二、很明显上面的语句将会在控制台输出一个字符串“Hello World!”，那么这个控制台程序的CIL语言是怎样的呢？我们下面可以通过VS2010自带的SDK工具IL Disassembler（ILDASM）打开上面应用程序创建的ConsoleApplication6.exe文件，以查看其CIL语言。如下图方式以打开ILDASM工具：</p>
<p><img src="http://pic002.cnblogs.com/images/2011/140041/2011062612595958.jpg" alt="" /></p>
<p>打开ILDASM工具界面如下：</p>
<p><img src="http://pic002.cnblogs.com/images/2011/140041/2011062613012761.jpg" alt="" /></p>
<p>本图代表一个ConsoleApplication6的命名空间下有一个类叫ConsoleApplication6.Program，这个类下面有一个类清单(.class private auto ansi beforefieldinit)+默认构造函数(.ctor:void())+静态函数(Main:void(string[]))。</p>
<p>注意：上图的界面中有一些红色的三角形，或者蓝色的盾形等分别代表更多信息或者是命名空间等信息，其具体含义如下图所示：</p>
<p><img src="http://pic002.cnblogs.com/images/2011/140041/2011062613010269.jpg" alt="" /></p>
<p>三、点击默认构造函数.ctor:void()我们可以看到这个构造函数的CIL语言如下：</p>
<pre class="brush:csharp">        .method public hidebysig specialname rtspecialname
            //.method表示对方法
        instance void  .ctor() cil managed
        {
          // 代码大小       7 (0x7)
          .maxstack  8
          IL_0000:  ldarg.0
          IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
          IL_0006:  ret
        } // end of method Program::.ctor</pre>
<p>ldarg.0 将索引为 0 的参数加载到计算堆栈上</p>
<p>call 调用由传递的方法说明符指示的方法</p>
<p>ret 从当前方法返回，并将返回值（如果存在）从调用方的计算堆栈推送到被调用方的计算堆栈上</p>
<p>意义：将索引为0的参数加载到堆栈上，然后调用System.Object对象的构造函数实例化对象，然后返回。</p>
<p>四、点击静态函数Main:void(string[])，可以打开一个界面，界面内看到CIL语言如下：</p>
<pre class="brush:csharp">.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint           //程序进入点
  // 代码大小       15 (0xf)
  .maxstack  1          //堆栈分配
  .locals init ([0] string a)
  IL_0000:  nop
  IL_0001:  ldstr      "Hello World!"//压入字符串,堆栈压操作
  IL_0006:  stloc.0     //从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中。
  IL_0007:  ldloc.0     //将索引 0 处的局部变量加载到计算堆栈上。
  IL_0008:  call       void [mscorlib]System.Console::WriteLine(string)
                        //呼叫WriteLine函数打印Hello World
  IL_000d:  nop
  IL_000e:  ret                             //返回
} // end of method Program::Main</pre>
<p>        通过本文章，我们初步的认识了CIL中间语言。也认识了一些CIL的指令代码</p>
<div style="background:#c1c1c1; font-size:12px;">
<ul>
<li>文章来源：博客园</li>
<li>作者：程兴亮</li>
<li>原文标题：《由浅入深CIL系列:1.初步认识CIL通用中间语言》</li>
<li>原文地址:http://www.cnblogs.com/chengxingliang/archive/2011/06/27/2090578.html</li>
</ul>
</div>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fyou_qian_ru_shen_ren_shi_cil_tong_yong_zhong_jian_yu_yan_yi&title=%E7%94%B1%E6%B5%85%E5%85%A5%E6%B7%B1%E8%AE%A4%E8%AF%86CIL%E9%80%9A%E7%94%A8%E4%B8%AD%E9%97%B4%E8%AF%AD%E8%A8%80%EF%BC%88%E4%B8%80%EF%BC%89" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/you_qian_ru_shen_ren_shi_cil_tong_yong_zhong_jian_yu_yan_yi/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(转)做Java开发这一年</title>
		<link>http://www.topzs.com/tech-box/zhuan_zuo_java_kai_fa_zhe_yi_nian</link>
		<comments>http://www.topzs.com/tech-box/zhuan_zuo_java_kai_fa_zhe_yi_nian#comments</comments>
		<pubDate>Wed, 29 Jun 2011 06:12:48 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.topzs.com/?p=979</guid>
		<description><![CDATA[从去年到现在，从.NET转向Java开发（只是因为项目原因，绝对与平台好坏没有关系）差不多有一年的时间了。通过这一年时间也有些感触，想从几个面比较一下这两个平台。希望能做到客观公正。 语言 我原来是使用C#语言的，和现在的Java语言相比，现在的Java语言语法就停留在C# 2.0这个年代。语法结构都非常传统，中规中矩。很突出的一点是，因为缺少对闭包的支持，有些用C#很容易做到的，用Java需要写很多废话代码。 前几天InfoQ上发表了一篇英国卫报逐步采用Scala替换Java的文章里一句话用的很好：看Java的代码很容易让你只见树木，不见森林。因为为了实现某个功能，你需要太多的支撑代码，而实现功能的关键代码却迷失了。 举个例子：我需要一个排好序的用户列表，排序的依据是用户名字。很简单的需求对不。自然的代码肯定是这样的： IList&#60;User&#62; users = … users.OrderBy(user =&#62; user.Name); 而如果用Java实现同样的功能你可能要这样写： List&#60;User&#62; users = … Collections.sort(users,new Comparator&#60;User&#62;() { public int compare(User left, User right) { return left.getName().compareTo(right.getName()); } }); 第一：没有扩展方法的支持，只有借助静态的辅助类 第二：没有闭包的支持，非要写个难看的匿名类 其实我们只需要一个OrderBy，一看就明白，但现在多了这么多“无用”的代码，反而核心的价值（order by）却显得不那么重要了。这还是一个很简单的例子，在实际的项目中你会为此付出更多的代价，你要写出一堆味同嚼蜡的代码才能实现你想要的那个功能，而那个功能其实是很显而易见。 所以在语言层面，Java没有任何亮点，只觉得罗里罗嗦。 关于语言层面的比较，老赵写过很多，而且非常精彩，建议去欣赏一下。 不过Java也有那么很少几个有点意思的小东西：比如静态导入（脑袋提醒，这东西很早就在VB里出现了）、以及Java对Annotation的特殊支持让我们可以做一个更有意思的事情。 概念满天飞 做Java以来，让我感触最深的是在Java世界里概念满天飞。ORM，IOC，AOP，这几个在.NET的世界里也有，但没见过这么浓的，但是如果你做Java应用，你不熟悉这几个你都不好意思出去跟人打招呼，所以除了学习Java本身外还有一大堆开源框架等着你研究。 还有什么View Model，Presentation Model，Validator，BRO（Business Rule Object），BPO（Business Process Object）,BDD。关键是不仅是概念上存在这样的名词，它还大量的出现在代码里。代码里将概念描述得淋漓尽致，还规规矩矩。或许我土老帽了，我开发.NET三年有余，从来没整这些玩意儿。但是我一点也不怀疑我的代码难以阅读，难以维护。 配置文件，你能再多一点么 我超级厌恶Spring的配置文件（虽然你说这只是个框架，但貌似Java社区有这个趋向）。虽然Spring现在也增加了注解（Annotation）的支持，但是还有那么一些知道的和不知道的原因，项目中存在大量的配置文件。而且为了“模块性”，一个小小的配置文件又包含有几个配置文件。有配置controller的，有配置DAO的，有配置service的。额，还有那该死的Hibernate的hbm文件。我想，系统的复杂性就是这么一点一点的堆积而来的。 ASP.NET的配置文件一度也有变得更臃肿的趋势，但最后还是大大瘦身（.NET 4.0里默认的web.config很小了）。而且Attribute在.NET的第一个版本就出现了，很多可配置的东西都提供了Attribute的API和XML的API，所以没有历史遗留包袱。 开源，这个我喜欢 Java里的开源软件远远超过.NET的（这可能跟微软有一定的关系吧）。如果你想完成一项工作，总会有一个开源软件适合你。比如我们要做一个定时调度的任务，马上就有Quartz跑到了你的视野，你只需实现几个接口，然后在配置文件里配置一下（又是该死的配置文件），又比如你苦于在Java里没法像C#里那样用Lambda，马上有个跟你一样想法的人开发了一个lambda4j（Java人有个说法是：语言不足类库来补，不过Java这个语言太不足了，所以有的时候类库补也补不好）。你可以在琳琅满目的开源框架和开源类库里寻找一个最合适的，然后打开这个潘多拉魔盒。最主要的是她还是开放的，你不仅可以学习其代码思想，如果你发现有问题你甚至可以提交代码，那种成就感我倒是在开发.NET时没有感觉到。比如你要开发高性能服务器，在.NET里还没见过这类的开源项目，可Java里你可以学习Netty，可以学习Mina，你甚至可以根据自己具体的业务场景，对这些开源软件进行适当的修改。当然，你可以说思想是一样的，这倒是不错。但因为IO模型在Java里和.NET里并不一样，所以还是有很多不同的（当然我觉得.NET的异步IO更容易使用，Java的NIO那是什么狗屎一样的API啊）。 IDE [...]]]></description>
			<content:encoded><![CDATA[<p>从去年到现在，从.NET转向Java开发（只是因为项目原因，绝对与平台好坏没有关系）差不多有一年的时间了。通过这一年时间也有些感触，想从几个面比较一下这两个平台。希望能做到客观公正。</p>
<h3>语言</h3>
<p>我原来是使用C#语言的，和现在的Java语言相比，现在的Java语言语法就停留在C# 2.0这个年代。语法结构都非常传统，中规中矩。很突出的一点是，因为缺少对闭包的支持，有些用C#很容易做到的，用Java需要写很多废话代码。</p>
<p>前几天InfoQ上发表了一篇英国卫报逐步采用Scala替换Java的文章里一句话用的很好：看Java的代码很容易让你只见树木，不见森林。因为为了实现某个功能，你需要太多的支撑代码，而实现功能的关键代码却迷失了。</p>
<p>举个例子：我需要一个排好序的用户列表，排序的依据是用户名字。很简单的需求对不。自然的代码肯定是这样的：</p>
<p>IList&lt;User&gt; users = …</p>
<p>users.OrderBy(user =&gt; user.Name);</p>
<p>而如果用Java实现同样的功能你可能要这样写：</p>
<p>List&lt;User&gt; users = …</p>
<p>Collections.sort(users,new Comparator&lt;User&gt;() {<br />
public int compare(User left, User right) {<br />
return left.getName().compareTo(right.getName());<br />
}<br />
});</p>
<p>第一：没有扩展方法的支持，只有借助静态的辅助类</p>
<p>第二：没有闭包的支持，非要写个难看的匿名类</p>
<p>其实我们只需要一个OrderBy，一看就明白，但现在多了这么多“无用”的代码，反而核心的价值（order by）却显得不那么重要了。这还是一个很简单的例子，在实际的项目中你会为此付出更多的代价，你要写出一堆味同嚼蜡的代码才能实现你想要的那个功能，而那个功能其实是很显而易见。</p>
<p>所以在语言层面，Java没有任何亮点，只觉得罗里罗嗦。</p>
<p>关于语言层面的比较，<a href="http://blog.zhaojie.me/2010/04/speech-why-java-sucks-and-csharp-rocks.html">老赵写过很多</a>，而且非常精彩，建议去欣赏一下。</p>
<p>不过Java也有那么很少几个有点意思的小东西：比如静态导入（脑袋提醒，这东西很早就在VB里出现了）、以及Java对Annotation的特殊支持让我们可以做一个更有意思的事情。<span id="more-979"></span></p>
<h3>概念满天飞</h3>
<p>做Java以来，让我感触最深的是在Java世界里概念满天飞。ORM，IOC，AOP，这几个在.NET的世界里也有，但没见过这么浓的，但是如果你做Java应用，你不熟悉这几个你都不好意思出去跟人打招呼，所以除了学习Java本身外还有一大堆开源框架等着你研究。</p>
<p>还有什么View Model，Presentation Model，Validator，BRO（Business Rule Object），BPO（Business Process Object）,BDD。关键是不仅是概念上存在这样的名词，它还大量的出现在代码里。代码里将概念描述得淋漓尽致，还规规矩矩。或许我土老帽了，我开发.NET三年有余，从来没整这些玩意儿。但是我一点也不怀疑我的代码难以阅读，难以维护。</p>
<h3>配置文件，你能再多一点么</h3>
<p>我超级厌恶Spring的配置文件（虽然你说这只是个框架，但貌似Java社区有这个趋向）。虽然Spring现在也增加了注解（Annotation）的支持，但是还有那么一些知道的和不知道的原因，项目中存在大量的配置文件。而且为了“模块性”，一个小小的配置文件又包含有几个配置文件。有配置controller的，有配置DAO的，有配置service的。额，还有那该死的Hibernate的hbm文件。我想，系统的复杂性就是这么一点一点的堆积而来的。</p>
<p>ASP.NET的配置文件一度也有变得更臃肿的趋势，但最后还是大大瘦身（.NET 4.0里默认的web.config很小了）。而且Attribute在.NET的第一个版本就出现了，很多可配置的东西都提供了Attribute的API和XML的API，所以没有历史遗留包袱。</p>
<h3>开源，这个我喜欢</h3>
<p>Java里的开源软件远远超过.NET的（这可能跟微软有一定的关系吧）。如果你想完成一项工作，总会有一个开源软件适合你。比如我们要做一个定时调度的任务，马上就有Quartz跑到了你的视野，你只需实现几个接口，然后在配置文件里配置一下（又是该死的配置文件），又比如你苦于在Java里没法像C#里那样用Lambda，马上有个跟你一样想法的人开发了一个lambda4j（Java人有个说法是：语言不足类库来补，不过Java这个语言太不足了，所以有的时候类库补也补不好）。你可以在琳琅满目的开源框架和开源类库里寻找一个最合适的，然后打开这个潘多拉魔盒。最主要的是她还是开放的，你不仅可以学习其代码思想，如果你发现有问题你甚至可以提交代码，那种成就感我倒是在开发.NET时没有感觉到。比如你要开发高性能服务器，在.NET里还没见过这类的开源项目，可Java里你可以学习Netty，可以学习Mina，你甚至可以根据自己具体的业务场景，对这些开源软件进行适当的修改。当然，你可以说思想是一样的，这倒是不错。但因为IO模型在Java里和.NET里并不一样，所以还是有很多不同的（当然我觉得.NET的异步IO更容易使用，Java的NIO那是什么狗屎一样的API啊）。</p>
<h3>IDE</h3>
<p>搞开发的肯定离不开IDE。.NET里的IDE当之无愧的是Visual Studio了。不过我却觉得Visual Studio这几年已经离开发人员越来越远了，好像他要搞什么全生命周期的软件开发工具。所以不但臃肿，而且对开发人员并不是很友好（当然，她的可视化设计器是无与伦比的，但我不觉得可视化设计器是什么开发人员的“利器”）。举两个例子：VS里大量使用组合快捷键。这样不仅使得快捷键过长，难以记忆，而且还好难使用啊，你必须按两次，而且时间不能间隔太长。还有VS的重构功能，太弱了。</p>
<p>在Java里有各种各样的IDE，有免费的，有收费的。我很喜欢的一个就是Intellij Idea。Idea给我的印象就是，她真的是在关注开发人员（写代码的）这个角色。所有的快捷键都很简单，好用好记。比如，大部分东西在Idea里可以使用Alt+Enter这个万能快捷键解决（这个快捷键是上下文感知的，在不同上下文中它知道要干什么）。</p>
<p>再就是Idea对重构的支持，如果你熟练之后，做一项大的重构你都无需手动的去修改什么代码，直接依靠IDE的支持就可以完成，这在安全的重构里是很重要的一点，手动的去修改代码重构如果在测试不完备的情况下风险是非常高的。</p>
<p>当然VS也有很多非常好用的插件，可以提高开发效率。比如大名鼎鼎的Resharper就来自于Intellij Idea同一个公司，由这个插件你可以看到Idea是如何关注写代码的人的效率。</p>
<h3>JVM vs CLR</h3>
<p>一般的，Java跑在JVM上，C#跑在CLR上。从技术实现上他们两平分秋色，各有各的优点，我们不能评价他们的好坏。只能说可能JVM在XXX上胜过CLR，CLR在XXX上胜过JVM。而且JVM和CLR有居多相似之处，大多数东西都可以在对方找到相应的东西。</p>
<p>那么她们就无法比较了么？不是，经过一年的学习我表示我更喜欢JVM一点。</p>
<p>JVM（在这里只假设是Oracle/Sun Hotspot JVM）暴露了众多的配置参数给开发人员。你可以通过这些参数间接地控制JVM的运行。就比如GC吧，JVM里有各种参数来控制各个代的大小，还可以通过参数让JVM采用什么样的垃圾收集策略。因为不同类型的应用：比如桌面的、服务器端得、内存小的等等不同类型的应用适合不同的垃圾收集策略。而CLR在垃圾收集上只给开发人员提供了Workstation（是否是concurrent GC，.net 4.0是background GC）/Server等很少的控制（不过也几乎很少用到）。当然，如果你想最大化控制CLR你就只有自己Host CLR，然后调用Host API进行控制，但是那样难度高很多。</p>
<p><strong>我很愿意承认</strong>CLR是自适应的，她能自动的智能的识别出你的需求，然后自动的进行调整。不过我在这里主要想到的是，微软在这里扮演着保姆的角色。在你很小的时候，保姆能够在一定程度上保护你，免你受到伤害。但是你不能永远生活在保姆的怀抱里，如果你想变得更强大你需要自己独自一人出去看看。</p>
<p><strong>注：这一节不是比较JVM和CLR，因为我没有那个能力。只是想从JVM和CLR所表现出来的差异来看看一些“看不见的东西”。</strong></p>
<h3>开发人员</h3>
<p>上面主要谈了技术层面的东西。现在说说软件开发中的人。</p>
<p>我现在所在的公司面试有个特点：会让面试者做一份家庭作业，然后让公司同事Code Review。在这一年里我看了很多Java的代码，也看了很多C#代码。但是我伤心的发现：</p>
<p>1、虽然Java的也有烂代码，但是Java代码大多更注意代码的美感。大家都非常注意选择方法名，变量名，类名等。也非常愿意写一些小的，容易理解的方法，小的目的明确的类。可我亲爱的.NET同行们，大多在这方面很随意。一个方法200行不算长，甚至一个功能就放到一个方法里实现了。我看呀看呀，都看不到尽头。更别说类职责单一了。</p>
<p>2、测试 Java同学的代码大多有测试，虽然有的测试不怎么好，但最起码有那么几个测测核心功能。但是.NET代码呢？很难见到几个有测试的（难道这是因为VS很晚才加入对Unit Test的支持有关？）。我不是说一定要有测试，我只是描述一下这么个现象。</p>
<p>3、你也太随意了。我见到有那么几份.NET代码，我知道你创建了一个WinForm的项目，然后你却不把VS自动生成的那几个Form1.cs,Form1.resx给删掉。</p>
<p>4、构建 从构建这个层面就更显出问题了，Java同学提交的代码大多有构建的脚本，无论是Ant还是Maven，所以你只需要敲一个命令行，马上可以看见人家的结果。而.NET同学的基本上都是sln文件。这一点不是说谁好谁坏的，因为我之前做.NET也从来没有自动构建脚本，我只想说两个社区有些不同。</p>
<h3>后记</h3>
<p>我在这里并不是贬低某个社区的开发人员，也不想扯进任何平台的纷争。因为这只是我看到的现象，还有很多是我没看到的，而且这也严重的受到我周围同事的影响，所以难免以偏概全。</p>
<p>如果有不足地方请不吝指教。</p>
<p>&nbsp;</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fzhuan_zuo_java_kai_fa_zhe_yi_nian&title=%28%E8%BD%AC%29%E5%81%9AJava%E5%BC%80%E5%8F%91%E8%BF%99%E4%B8%80%E5%B9%B4" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/zhuan_zuo_java_kai_fa_zhe_yi_nian/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Silverlight故事扳(storyboard)元素表</title>
		<link>http://www.topzs.com/tech-box/silverlight_gu_shi_ban_storyboard_yuan_su_biao</link>
		<comments>http://www.topzs.com/tech-box/silverlight_gu_shi_ban_storyboard_yuan_su_biao#comments</comments>
		<pubDate>Mon, 09 May 2011 06:32:26 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[Silverlight故事扳]]></category>
		<category><![CDATA[storyboard]]></category>

		<guid isPermaLink="false">http://www.topzs.com/tech-box/silverlight_gu_shi_ban_storyboard_yuan_su_biao</guid>
		<description><![CDATA[元素 DoubleAnimation 表示用于double类型属性的值 比如 Rectangle的Width height等等 当作一个double变量的值 ColorAnimation 表示用于Color类型属性的值 Rectangle的Fill Background 等等 PointAnimation 表示用于Point类型属性的值 EllipseGeometry的Center Animation对象的属性 Form属性 表示指定一个元素的值 它的意思就是从哪******* 比如说Rectangle的Width 从200开始作动画 To属性 表示从Form指定的值到to的值 它的意思就是从什么值到什么值 上面xaml代码已经说明了 宽度从200到500 by属性 表示 Form+by指定的值=to的值 也就是说 Form是200 by是300 那么等于to的500值 如果不设置Form属性 它会用元素自身的值 比如说 Rectangle的Width是200 by指定是300 那么200+300=500的宽度 第二次运行故事版 从500开始再加300 那就是800的宽度 BeginTime属性 表示推迟开始的时间 值的格式就是小时:分钟:分秒 比如0:0:5表示5秒 Duration属性 表示动画待续的时间 值的格式就是小时:分钟:分秒 比如0:0:5表示5秒 RepeatBehaviour属性 表示重复动画播放 第一种值是次数+X 比如1X 表示一次 [...]]]></description>
			<content:encoded><![CDATA[<p>元素</p>
<p> DoubleAnimation 表示用于double类型属性的值 比如 Rectangle的Width height等等 当作一个double变量的值</p>
<p> ColorAnimation 表示用于Color类型属性的值 Rectangle的Fill Background 等等</p>
<p> PointAnimation 表示用于Point类型属性的值 EllipseGeometry的Center</p>
<p> Animation对象的属性</p>
<p> Form属性 表示指定一个元素的值 它的意思就是从哪******* 比如说Rectangle的Width 从200开始作动画</p>
<p> To属性 表示从Form指定的值到to的值 它的意思就是从什么值到什么值 上面xaml代码已经说明了 宽度从200到500</p>
<p> by属性 表示 Form+by指定的值=to的值 也就是说 Form是200 by是300 那么等于to的500值 如果不设置Form属性 它会用元素自身的值 比如说 Rectangle的Width是200 by指定是300 那么200+300=500的宽度 第二次运行故事版 从500开始再加300 那就是800的宽度</p>
<p> BeginTime属性 表示推迟开始的时间 值的格式就是小时:分钟:分秒 比如0:0:5表示5秒</p>
<p> Duration属性 表示动画待续的时间 值的格式就是小时:分钟:分秒 比如0:0:5表示5秒</p>
<p> RepeatBehaviour属性 表示重复动画播放 第一种值是次数+X 比如1X 表示一次 4X表示四次重复 第二种值是时间段 跟Duration有关 假设Duration设置2秒 那RepeatBehaviour设置4秒表示两次重复 第三种值是Forever 表示无限重复</p>
<p> AutoReverse属性 表示自动返回播放 意思就是从开始到结束然后从结束到开始</p>
<p> FillBehaviour属性 表示动画结束时候希望结束停在哪 HoldEnd表示停在结束当前的值 Stop表示结束后停在开始的值</p>
<p> SpeedRatio属性 表示动画加速 1表示正常速 2表示双倍速 0.5表示半速</p>
<p> EasingFunction属性 表示缓动函数 意思就是封装好的公用计算的动画 有时候自己编写动画逼真的效果运算很耗时间 可以参考这个属性减少时间 http://samples.msdn.microsoft.com/Silverlight/silverlight_next/Animations/easing_functions_gallery/testpage.html</p>
<p> storyboard对象属性和Animation属性类似 不同是它提供一些控制动画方法 比如 Begin方法 参考http://msdn.microsoft.com/zh-cn/library/system.windows.media.animation.storyboard_members(v=VS.95).aspx 已经详细介绍了</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fsilverlight_gu_shi_ban_storyboard_yuan_su_biao&title=Silverlight%E6%95%85%E4%BA%8B%E6%89%B3%28storyboard%29%E5%85%83%E7%B4%A0%E8%A1%A8" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/silverlight_gu_shi_ban_storyboard_yuan_su_biao/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C#使用指针实现马赛克效果</title>
		<link>http://www.topzs.com/tech-box/c_shi_yong_zhi_zhen_shi_xian_ma_sai_ke_xiao_guo</link>
		<comments>http://www.topzs.com/tech-box/c_shi_yong_zhi_zhen_shi_xian_ma_sai_ke_xiao_guo#comments</comments>
		<pubDate>Tue, 12 Apr 2011 15:52:08 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[GDI+]]></category>
		<category><![CDATA[指针]]></category>
		<category><![CDATA[马赛克]]></category>

		<guid isPermaLink="false">http://www.topzs.com/?p=964</guid>
		<description><![CDATA[/// &#60;summary&#62; /// 马赛克效果 ///原理：确定图像的随机位置点和确定马赛克块的大小,然后马赛克块图像覆盖随机点即可. /// &#60;/summary&#62; /// &#60;param name="m_Iimage"&#62;&#60;/param&#62; /// &#60;param name="val"&#62;分割成val*val像素的小区块&#60;/param&#62; public Image MaSaiKe(Image m_PreImage , int val) { Bitmap MyBitmap = new Bitmap(m_PreImage); if (MyBitmap.Equals(null)) { return null; } int iWidth = MyBitmap.Width; int iHeight = MyBitmap.Height; int stdR , stdG , stdB; stdR = 0; stdG = 0; stdB = 0; [...]]]></description>
			<content:encoded><![CDATA[<div>
<pre class="brush:csharp">       /// &lt;summary&gt;
       /// 马赛克效果
        ///原理：确定图像的随机位置点和确定马赛克块的大小,然后马赛克块图像覆盖随机点即可.
        /// &lt;/summary&gt;
        /// &lt;param name="m_Iimage"&gt;&lt;/param&gt;
        /// &lt;param name="val"&gt;分割成val*val像素的小区块&lt;/param&gt;
        public Image MaSaiKe(Image m_PreImage , int val)
        {
            Bitmap MyBitmap = new Bitmap(m_PreImage);
            if (MyBitmap.Equals(null))
            {
                return null;
            }
            int iWidth = MyBitmap.Width;
            int iHeight = MyBitmap.Height;
            int stdR , stdG , stdB;
            stdR = 0;
            stdG = 0;
            stdB = 0;
            BitmapData srcData = MyBitmap.LockBits(new Rectangle(0 , 0 , iWidth , iHeight) ,
            ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb);
            unsafe
            {
                byte* point = (byte*)srcData.Scan0.ToPointer();
                for (int i = 0; i &lt; iHeight; i++)
                {
                    for (int j = 0; j &lt; iWidth; j++)
                    {
                        if (i % val == 0)
                        {
                            if (j % val == 0)
                            {
                                stdR = point[2];
                                stdG = point[1];
                                stdB = point[0];
                            }
                            else
                            {
                                point[0] = (byte)stdB;
                                point[1] = (byte)stdG;
                                point[2] = (byte)stdR;
                            }
                        }
                        else
                        {
                            //复制上一行
                            byte* pTemp = point - srcData.Stride;
                            point[0] = (byte)pTemp[0];
                            point[1] = (byte)pTemp[1];
                            point[2] = (byte)pTemp[2];
                        }
                        point += 3;
                    }
                    point += srcData.Stride - iWidth * 3;
                }
                MyBitmap.UnlockBits(srcData);
            }
            return MyBitmap;
        }</pre>
</div>
<p><a href="http://hi.csdn.net/attachment/201104/11/1924493_1302497782EJ99.png" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone" title="效果图" src="http://hi.csdn.net/attachment/201104/11/1924493_1302497782EJ99.png" alt="" width="720" height="441" /></a></p>
<p>作者：<dfn><a onclick="LogClickCount(this,111);" href="http://hi.csdn.net/xx_mm" target="_blank"><span style="color: #333333;">xx_mm</span></a></dfn></p>
<p>原文标题：分享一段C#使用指针的代码！！</p>
<p>原文连接：<a href="http://topic.csdn.net/u/20110411/12/4a44f138-b8f5-4d72-82eb-6b153eca360e.html">http://topic.csdn.net/u/20110411/12/4a44f138-b8f5-4d72-82eb-6b153eca360e.html</a></p>
<div id="_mcePaste" class="mcePaste" style="position: absolute; width: 1px; height: 1px; overflow: hidden; top: 0px; left: -10000px;">﻿</div>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fc_shi_yong_zhi_zhen_shi_xian_ma_sai_ke_xiao_guo&title=C%23%E4%BD%BF%E7%94%A8%E6%8C%87%E9%92%88%E5%AE%9E%E7%8E%B0%E9%A9%AC%E8%B5%9B%E5%85%8B%E6%95%88%E6%9E%9C" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/c_shi_yong_zhi_zhen_shi_xian_ma_sai_ke_xiao_guo/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DevExpress中的gridControl图片的显示</title>
		<link>http://www.topzs.com/tech-box/devexpress_zhong_de_gridcontrol_tu_pian_de_xian_shi</link>
		<comments>http://www.topzs.com/tech-box/devexpress_zhong_de_gridcontrol_tu_pian_de_xian_shi#comments</comments>
		<pubDate>Mon, 28 Mar 2011 04:16:59 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[DevExpress]]></category>

		<guid isPermaLink="false">http://www.topzs.com/tech-box/devexpress_zhong_de_gridcontrol_tu_pian_de_xian_shi</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160;&#160;&#160;&#160; private void showData(List&#60;Employee &#62; list) &#160;&#160;&#160;&#160;&#160;&#160;&#160; { &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataTable dt = new DataTable(&#34;OneEmployee&#34;); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dt.Columns.Add(&#34;Caption&#34;, System.Type.GetType(&#34;System.String&#34;)); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dt.Columns.Add(&#34;Department&#34;, System.Type.GetType(&#34;System.String&#34;)); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dt.Columns.Add(&#34;PhotoName&#34;, System.Type.GetType(&#34;System.Byte[]&#34;)); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (int i = 0; i &#60; list.Count; i++) &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataRow dr = dt.NewRow(); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dr[&#34;Caption&#34;] = list[i].Name; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dr[&#34;Department&#34;] = list[i].Department; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string imagePath = @&#34;D:\C#\photos\&#34; + list[i].PhotoPath; [...]]]></description>
			<content:encoded><![CDATA[<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; private void showData(List&lt;Employee &gt; list)   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataTable dt = new DataTable(&quot;OneEmployee&quot;);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dt.Columns.Add(&quot;Caption&quot;, System.Type.GetType(&quot;System.String&quot;));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dt.Columns.Add(&quot;Department&quot;, System.Type.GetType(&quot;System.String&quot;));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dt.Columns.Add(&quot;PhotoName&quot;, System.Type.GetType(&quot;System.Byte[]&quot;)); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (int i = 0; i &lt; list.Count; i++)   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataRow dr = dt.NewRow();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dr[&quot;Caption&quot;] = list[i].Name;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dr[&quot;Department&quot;] = list[i].Department;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string imagePath = @&quot;D:\C#\photos\&quot; + list[i].PhotoPath;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dr[&quot;PhotoName&quot;] = getImageByte(imagePath);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dt.Rows.Add(dr);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gridControl1.DataSource = dt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; //返回图片的字节流byte[]   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private byte[] getImageByte(string imagePath)    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FileStream files = new FileStream(imagePath, FileMode.Open);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; byte[] imgByte = new byte [files.Length ];    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; files.Read(imgByte, 0, imgByte.Length);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; files.Close();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return imgByte;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/alen0707/archive/2009/05/20/4203807.aspx</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fdevexpress_zhong_de_gridcontrol_tu_pian_de_xian_shi&title=DevExpress%E4%B8%AD%E7%9A%84gridControl%E5%9B%BE%E7%89%87%E7%9A%84%E6%98%BE%E7%A4%BA" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/devexpress_zhong_de_gridcontrol_tu_pian_de_xian_shi/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DevExpress中GridControl的属性设置</title>
		<link>http://www.topzs.com/tech-box/devexpress_zhong_gridcontrol_de_shu_xing_she_zhi</link>
		<comments>http://www.topzs.com/tech-box/devexpress_zhong_gridcontrol_de_shu_xing_she_zhi#comments</comments>
		<pubDate>Mon, 28 Mar 2011 04:09:35 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[DevExpress]]></category>
		<category><![CDATA[Winfrom]]></category>

		<guid isPermaLink="false">http://www.topzs.com/tech-box/devexpress_zhong_gridcontrol_de_shu_xing_she_zhi</guid>
		<description><![CDATA[1.隐藏最上面的GroupPanel &#160; gridView1.OptionsView.ShowGroupPanel=false; 2.得到当前选定记录某字段的值 &#160; sValue=Table.Rows[gridView1.FocusedRowHandle][FieldName].ToString(); 3.数据只读 &#160; gridView1.OptionsBehavior.Editable=false; 4.不显示MasterDetailView gridView1.OptionsDetail.EnableMasterViewMode=false; 5.修改最上面的GroupPanel内容 gridView1.GroupPanelText=&#34;柳生飘絮&#34;; 6.数据绑定： FieldName －－数据库的字段名称 7.读写拷贝权限设置 ColumnView.Editable &#160;&#160;&#160; This property returns a value of the ColumnViewOptionsBehavior.Editable option &#160;&#160;&#160; 不可写 ColumnViewOptionsBehavior.Editable &#160;&#160;&#160; Gets or sets whether end users are allowed to invoke cell editors &#160;&#160;&#160; 可读可写 OptionsColumn.AllowEdit &#160;&#160;&#160; Gets or sets whether end users are [...]]]></description>
			<content:encoded><![CDATA[<p>1.隐藏最上面的GroupPanel </p>
<p>&#160; gridView1.OptionsView.ShowGroupPanel=false; </p>
<p>2.得到当前选定记录某字段的值 </p>
<p>&#160; sValue=Table.Rows[gridView1.FocusedRowHandle][FieldName].ToString(); </p>
<p>3.数据只读 </p>
<p>&#160; gridView1.OptionsBehavior.Editable=false; </p>
<p>4.不显示MasterDetailView </p>
<p>gridView1.OptionsDetail.EnableMasterViewMode=false; </p>
<p>5.修改最上面的GroupPanel内容 </p>
<p><span id="more-957"></span>
</p>
<p>gridView1.GroupPanelText=&quot;柳生飘絮&quot;; </p>
<p>6.数据绑定： </p>
<p>FieldName －－数据库的字段名称 </p>
<p>7.读写拷贝权限设置 </p>
<p>ColumnView.Editable   <br />&#160;&#160;&#160; This property returns a value of the ColumnViewOptionsBehavior.Editable option    <br />&#160;&#160;&#160; 不可写    <br />ColumnViewOptionsBehavior.Editable    <br />&#160;&#160;&#160; Gets or sets whether end users are allowed to invoke cell editors    <br />&#160;&#160;&#160; 可读可写 </p>
<p>OptionsColumn.AllowEdit   <br />&#160;&#160;&#160; Gets or sets whether end users are allowed to invoke editors for the column&#8217;s cells.    <br />&#160;&#160;&#160; 可读可写    <br />&#160;&#160;&#160; 只有ColumnViewOptionsBehavior.Editable = True设置OptionsColumn.AllowEdit才有意义 </p>
<p>OptionsColumn.ReadOnly   <br />&#160;&#160;&#160; Gets or sets whether end-users are prevented from editing the column&#8217;s cell values.     <br />&#160;&#160;&#160; 可读可写 </p>
<p>If the ReadOnly property is set to true, the cell values of columns cannot be modified by end-users. In this case cell editors can be invoked but end users can only select and copy an editor&#8217;s content. This option is not in effect if the column&#8217;s AllowEdit or the view&#8217;s ColumnView.Editable option is disabled. </p>
<p>Cell values can still be modified in code using the ColumnView.SetRowCellValue method regardless of the ReadOnly property&#8217;s setting. </p>
<p>只读不可拷贝：   <br />&#160;&#160;&#160; ColumnViewOptionsBehavior.Editable = False </p>
<p>只读可拷贝:   <br />&#160;&#160;&#160; ColumnViewOptionsBehavior.Editable = True    <br />&#160;&#160;&#160; OptionsColumn.AllowEdit = True    <br />&#160;&#160;&#160; OptionsColumn.ReadOnly = True </p>
<p>可编辑:   <br />&#160;&#160;&#160; ColumnViewOptionsBehavior.Editable = True    <br />&#160;&#160;&#160; OptionsColumn.AllowEdit = True    <br />&#160;&#160;&#160; OptionsColumn.ReadOnly = False </p>
<p>获取选中行的值 </p>
<p>代码： </p>
<p> private void gridData_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _id = GWEntLib.Utilities.Mix.ConvertUtils.ToInt32(gridData.GetRowCellValu(e.FocusedRowHandle, &quot;Id&quot;));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _emrFileReadList = EMRTemplateFileReadList.GetEMRTemplateFileReadList(_id);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gridVersonData.DataSource = _emrFileReadList;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />响应事件：FocusedRowChanged    <br />获取字段值：gridData.GetRowCellValue(e.FocusedRowHandle, &quot;Id&quot;)    <br />注意：FocusedRowChanged是Gridview的事件而不是gridControl的事件    <br />gridControl与Gridview的区别：前者是容器，后者为视图</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/liushengpiaoxu/archive/2008/12/01/3420996.aspx</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fdevexpress_zhong_gridcontrol_de_shu_xing_she_zhi&title=DevExpress%E4%B8%ADGridControl%E7%9A%84%E5%B1%9E%E6%80%A7%E8%AE%BE%E7%BD%AE" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/devexpress_zhong_gridcontrol_de_shu_xing_she_zhi/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用SQL Server Management Studio 2008 将数据库里的数据导成脚本</title>
		<link>http://www.topzs.com/tech-box/shi_yong_sql_server_management_studio_2008_jiang_shu_ju_ku_li_de_shu_ju_dao_cheng_jiao_ben</link>
		<comments>http://www.topzs.com/tech-box/shi_yong_sql_server_management_studio_2008_jiang_shu_ju_ku_li_de_shu_ju_dao_cheng_jiao_ben#comments</comments>
		<pubDate>Fri, 25 Mar 2011 01:32:29 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[脚本]]></category>

		<guid isPermaLink="false">http://www.topzs.com/tech-box/shi_yong_sql_server_management_studio_2008_jiang_shu_ju_ku_li_de_shu_ju_dao_cheng_jiao_ben</guid>
		<description><![CDATA[之前很羡慕MySQL 有这样的工具可以把数据库里的数据导成脚本，SQL Server 2005 的时候大牛Pinal Dave写了个Database Publishing Wizard，具体用法参考他写的文章SQL SERVER – 2005 – Generate Script with Data from Database – Database Publishing Wizard。SQL Server Management Studio 2008现在已经自带了这样的功能，下面我就来演示下如何使用： 1、打开SQL Server Management Studio 2008 ，连接到你的数据库服务器，展开对象资源管理器到数据库节点 2、选择需要将数据导出到脚本的数据库，我这里选择的是AdventureWorks ，将包含所有的存储过程，表，视图，表里的数据等等。 3、右击选中的数据，按照以下路径选择生成脚本向导 ：AdventureWorks -〉任务 -〉生成脚本 4、当点击生成脚本，弹出一个向导&#8211;生成数据库对象脚本： 5、下一步到达设置脚本编写选项，进入高级设置对话框，关键是要编写脚本的数据类型这里，默认是仅限架构，选择架构和数据或者是数据都可以吧数据导成脚本： 执行完就可以看到如下的结果了 作者: 自由、创新、研究、探索…… 出处：http://shanyou.cnblogs.com/ 版权：本文版权归作者和博客园共有 转载：欢迎转载，为了保存作者的创作热情，请按要求【转载】，谢谢 要求：未经作者同意，必须保留此段声明；必须在文章中给出原文连接；否则必究法律责任]]></description>
			<content:encoded><![CDATA[<p>之前很羡慕MySQL 有这样的工具可以把数据库里的数据导成脚本，SQL Server 2005 的时候大牛Pinal Dave写了个<a href="http://www.codeplex.com/sqlhost/Wiki/View.aspx?title=Database%20Publishing%20Wizard">Database Publishing Wizard</a>，具体用法参考他写的文章<a href="http://blog.sqlauthority.com/2007/11/16/sql-server-2005-generate-script-with-data-from-database-database-publishing-wizard/">SQL SERVER – 2005 – Generate Script with Data from Database – Database Publishing Wizard</a>。SQL Server Management Studio 2008现在已经自带了这样的功能，下面我就来演示下如何使用：</p>
<p>1、打开SQL Server Management Studio 2008 ，连接到你的数据库服务器，展开对象资源管理器到数据库节点</p>
<p>2、选择需要将数据导出到脚本的数据库，我这里选择的是AdventureWorks ，将包含所有的存储过程，表，视图，表里的数据等等。</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242209266570.png" class="highslide-image" onclick="return hs.expand(this);"><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242209409229.png" width="474" height="259" /></a></p>
<p>3、右击选中的数据，按照以下路径选择生成脚本向导 ：AdventureWorks -〉任务 -〉生成脚本</p>
<p><span id="more-956"></span>
</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242209527384.png" class="highslide-image" onclick="return hs.expand(this);"><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242210035390.png" width="458" height="236" /></a></p>
<p>4、当点击生成脚本，弹出一个向导&#8211;生成数据库对象脚本：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/shanyou/201103/20110324221012811.png" class="highslide-image" onclick="return hs.expand(this);"><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242210237770.png" width="460" height="306" /></a></p>
<p>5、下一步到达设置脚本编写选项，进入高级设置对话框，关键是要编写脚本的数据类型这里，默认是仅限架构，选择架构和数据或者是数据都可以吧数据导成脚本：</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242210347628.png" class="highslide-image" onclick="return hs.expand(this);"><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242210429626.png" width="458" height="397" /></a></p>
<p>执行完就可以看到如下的结果了</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242210489588.png" class="highslide-image" onclick="return hs.expand(this);"><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/shanyou/201103/201103242210554303.png" width="460" height="434" /></a></p>
<p>作者: <a href="http://shanyou.cnblogs.com/">自由、创新、研究、探索……</a>     <br />出处：<a href="http://shanyou.cnblogs.com/">http://shanyou.cnblogs.com/</a>     <br />版权：本文版权归作者和博客园共有     <br />转载：欢迎转载，为了保存作者的创作热情，请按要求【转载】，谢谢     <br />要求：未经作者同意，必须保留此段声明；必须在文章中给出原文连接；否则必究法律责任</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fshi_yong_sql_server_management_studio_2008_jiang_shu_ju_ku_li_de_shu_ju_dao_cheng_jiao_ben&title=%E4%BD%BF%E7%94%A8SQL+Server+Management+Studio+2008+%E5%B0%86%E6%95%B0%E6%8D%AE%E5%BA%93%E9%87%8C%E7%9A%84%E6%95%B0%E6%8D%AE%E5%AF%BC%E6%88%90%E8%84%9A%E6%9C%AC" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/shi_yong_sql_server_management_studio_2008_jiang_shu_ju_ku_li_de_shu_ju_dao_cheng_jiao_ben/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server 2011中基于列的存储方式</title>
		<link>http://www.topzs.com/tech-box/sql_server_2011_zhong_ji_yu_lie_de_cun_chu_fang_shi</link>
		<comments>http://www.topzs.com/tech-box/sql_server_2011_zhong_ji_yu_lie_de_cun_chu_fang_shi#comments</comments>
		<pubDate>Wed, 23 Mar 2011 04:01:15 +0000</pubDate>
		<dc:creator>Topaz</dc:creator>
				<category><![CDATA[Tech Box]]></category>
		<category><![CDATA[列存储索引]]></category>

		<guid isPermaLink="false">http://www.topzs.com/?p=953</guid>
		<description><![CDATA[和大多数主流数据库一样，如果表拥有聚集索引，那么SQL Server就会以B-树的方式存储，否则就会使用堆的方式存储。这两种方法本质上都是基于行的，其中每页中行的条数会根据总体上行的大小不同而不同。从SQL Server 2011开始，微软为我们提供了第三种选择。SQL Server会提供一种“列存储索引”，从而以列而不是行的方式来存储数据。 当使用数据规模为1TB、记录条数为十四亿四千万的表时，微软声称基于列的查询在CPU时间上会有16倍的提升，而在使用时间上会有455倍的提高。在真实情况下，这意味着本来要耗费501秒的查询，现在只需要1.1秒就可以完成了。这项测试是在拥有32个逻辑处理器和256GB内存的计算机上执行的。 微软把每个列都隔离在自身的一组页中，从而达到了这种惊人的改善。当执行查询的时候，只会从磁盘载入位于结果集中的列。而包含其它列的页会被忽略。 这种方法相当于为每种我们所能想象到的列组合创建替代索引。然而，这种方式不会消耗大量的磁盘空间，它实际上会比传统的表占用更小的空间。由于SQL Server的压缩会发生在页级别上，并且和行相比，列中的数据更容易重复，所以使用列存储索引的表将会拥有更高的压缩等级。 但暂时我们还不能轻易决定使用列存储索引。首先也是最重要的，它们是不可更新的。一旦创建了列存储的索引，那么就不允许在表上执行插入、更新或者删除等操作了。微软期望更多商店每天对数据进行刷新，否则就需要把数据做只读处理。在刷新周期中，我们会删除索引，更新数据，然后再重新建立索引。由于这肯定是代价昂贵的操作，所以我们可以使用垂直分区来把操作限制到逻辑表的子集范围内。 使用列存储的索引也会导致性能的降低。如果你使用大多数列，那么重新组合行会耗费大量的资源。这意味着OLTP样式的查询应该避免这种方式，而对于OLAP形式的查询，这种方式会比较有利。或者换句话说，如果你在编写“SELECT *”或者每次抓取一行数据，那么列存储索引就不适合你。]]></description>
			<content:encoded><![CDATA[<p>和大多数主流数据库一样，如果表拥有聚集索引，那么SQL Server就会以<a href="http://en.wikipedia.org/wiki/B-tree">B-树</a>的方式存储，否则就会使用<a href="http://msdn.microsoft.com/en-us/library/ms188270.aspx">堆</a>的方式存储。这两种方法本质上都是基于行的，其中每页中行的条数会根据总体上行的大小不同而不同。从SQL Server 2011开始，微软为我们提供了第三种选择。SQL Server会提供一种“<a href="http://download.microsoft.com/download/8/C/1/8C1CE06B-DE2F-40D1-9C5C-3EE521C25CE9/Columnstore%20Indexes%20for%20Fast%20DW%20QP%20SQL%20Server%2011.pdf">列存储索引</a>”，从而以列而不是行的方式来存储数据。</p>
<p>当使用数据规模为1TB、记录条数为十四亿四千万的表时，微软声称基于列的查询在CPU时间上会有16倍的提升，而在使用时间上会有455倍的提高。在真实情况下，这意味着本来要耗费501秒的查询，现在只需要1.1秒就可以完成了。这项测试是在拥有32个逻辑处理器和256GB内存的计算机上执行的。</p>
<p>微软把每个列都隔离在自身的一组页中，从而达到了这种惊人的改善。当执行查询的时候，只会从磁盘载入位于结果集中的列。而包含其它列的页会被忽略。</p>
<p>这种方法相当于为每种我们所能想象到的列组合创建替代索引。然而，这种方式不会消耗大量的磁盘空间，它实际上会比传统的表占用更小的空间。由于SQL Server的压缩会发生在页级别上，并且和行相比，列中的数据更容易重复，所以使用列存储索引的表将会拥有更高的压缩等级。</p>
<p>但暂时我们还不能轻易决定使用列存储索引。首先也是最重要的，它们是不可更新的。一旦创建了列存储的索引，那么就不允许在表上执行插入、更新或者删除等操作了。微软期望更多商店每天对数据进行刷新，否则就需要把数据做只读处理。在刷新周期中，我们会删除索引，更新数据，然后再重新建立索引。由于这肯定是代价昂贵的操作，所以我们可以使用垂直分区来把操作限制到逻辑表的子集范围内。</p>
<p>使用列存储的索引也会导致性能的降低。如果你使用大多数列，那么重新组合行会耗费大量的资源。这意味着OLTP样式的查询应该避免这种方式，而对于OLAP形式的查询，这种方式会比较有利。或者换句话说，如果你在编写“SELECT *”或者每次抓取一行数据，那么列存储索引就不适合你。</p>
<p><a href="http://www.bshare.cn/share?url=http%3A%2F%2Fwww.topzs.com%2Ftech-box%2Fsql_server_2011_zhong_ji_yu_lie_de_cun_chu_fang_shi&title=SQL+Server+2011%E4%B8%AD%E5%9F%BA%E4%BA%8E%E5%88%97%E7%9A%84%E5%AD%98%E5%82%A8%E6%96%B9%E5%BC%8F" title="用bShare分享或收藏本文"><img src="http://static.bshare.cn/frame/images/button_custom1-zh.gif" alt="用bShare分享或收藏本文" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.topzs.com/tech-box/sql_server_2011_zhong_ji_yu_lie_de_cun_chu_fang_shi/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

