不用IDE写C#的Hello World

 用Visual Studio等IDE写C#的Hello World非常简单,但脱离了IDE你能不能打印出Hello World呢?这不是说工作时脱离IDE,而是学习一下CLR的执行模型.

  Hello World

  1. 新建一个记事本,输入如下代码,另存为HelloWorld.txt。

    using System;
    namespace HelloWorld
    {
       class Program
       {
            static void Main(string[] args) {
                Console.WriteLine("Hello World!");
                Console.ReadKey();
            }
        }
    }
  2. 打开Visual Studio 2008(2005,2010) 命令提示程序

  3. 切换到HelloWorld.txt的目录 
  4. 运行命令:csc /out:Hello.exe HelloWorld.txt 

  如无意外,将会编译出Hello.exe,能打印出Hello World。

  CLR执行模型-编译期

  CLR程序的执行过程大致分为两步,编译期和运行期,编译期过程大致如下图:

  其中编译期逻辑上也可分为两步:

  1. CLR(C#)编译器接受源代码文件,并编译为托管模块。托管模块包括IL代码、元数据、CLR头等组成部分。上面的例子中就是将HelloWorld.txt编译成托管模块。
  2. 一般程序集都会包含很多源代码文件(这里只有HelloWorld.txt)和资源文件,第二步就是把各个源代码文件和资源文件对应编译结果合并成程序集。

  执行上面两步就可以得到一个XX.dll或XX.exe的程序集,就像上面的Hello.exe。

  编译器如何知道要编译成托管模块还是资源文件?其实是必须明确告诉编译器每个文件的怎么编译,这个对应Visual Studio的文件属性的生成操作.

  右击任何Visual Studio解决资源方案的文件-->属性-->生成操作:

  指定Class1为嵌入的资源,用ILSpy查看会发现只是把Class1嵌入到程序集中,名称为:命名空间.文件名:

  你甚至可以将一张图片设为编译让编译器试图去编译它,不过会报错。

  运行期

  上面生成了程序集,程序集内的是IL代码,它还不是可运行的代码。IL是与CPU无关的机器语言,直到程序集被调用,才会由JIT(Just-in-Time,实时)编译器编译为本机代码(CPU指令)。在运行时,CLR执行如下步骤:

  1. 检查程序集的安全特性;
  2. 在内存中分配空间;
  3. 把程序集中的可执行代码发送给JIT编译器,把其中一部分编译成本机代码(CPU指令)。

  程序集的可执行代码在需要的时候由JIT编译器编译,然后本机代码(CPU指令)就被缓存以备后来的程序中执行。一旦应用程序终止,编译好的本机代码也会被丢弃。

  例如如果将上面的代码改为:

static void Main(string[] args) {
    Console.WriteLine("Hello");
    Console.WriteLine("World!");
    Console.ReadKey();
}

  第一个WriteLine需要先JIT编译,再执行。而由于已编译WriteLine的代码,所以第二个WriteLine会直接执行内存块中的代码,跳过JIT编译。

  由于分配内存、JIT编译过程等,所以程序会在第一次运行时造成一些性能损失,写ASP.NET时这种感觉特变明显,按了F5会等很久才会显示首页。

  下面模拟感受这个过程。用一大堆类延长内存分配的时间,参考这个文件HelloWorld.cs(博客园不支持txt格式):

  再次运行命令:csc /out:Hello.exe HelloWorld.txt,得到Hello.exe,执行时发现有一定的延迟才会打印出Hello World。

  生成本机代码

  使用.NET提供的NGen.exe,可以将IL代码编译成本机代码,可以解决上面的问题。NGen.exe有两个作用:

  1. 加快应用程序的启动速度。因为代码已编译为本机代码,运行时不需要再花时间编译。
  2. 减少应用程序的程序集。如果一个程序集会同时加载多个进程,NGen.exe会将IL编译成本机代码,并保存到一个单独的文件中。这样就可以通过"内存映射"的方式,同时映射到多个进程中,使代码共享,避免每个进程一份代码。

  再次运行 Visual Studio 2008(2005,2010) 命令提示程序

  运行如下命令:ngen install Hello.exe:


  命令完成(在我的机器大概要10秒左右,到能再次输入命令才完成)后,运行Hello.exe会发现马上就能打印出Hello World,没有任何延迟。

时间: 2024-12-28 14:32:20

不用IDE写C#的Hello World的相关文章

不用IDE写C#的Hello World的方法

不用IDE写C#的Hello World的方法 投稿:lijiao 字体:[增加 减小] 类型:转载 时间:2015-10-15我要评论 这篇文章主要介绍了不用IDE写C#的Hello World的方法,需要的朋友可以参考下 用Visual Studio等IDE写C#的Hello World非常简单,但脱离了IDE你能不能打印出Hello World呢?这不是说工作时脱离IDE,而是学习一下CLR的执行模型. Hello World 新建一个记事本,输入如下代码,另存为HelloWorld.tx

Delphi使用android的NDK是通过JNI接口,封装好了,不用自己写本地代码,直接调用

一.Android平台编程方式:      1.基于Android SDK进行开发的第三方应用都必须使用Java语言(Android的SDK基于Java实现)      2.自从ndk r5发布以后,已经允许完全用C/C++ 来开发应用或者游戏,而不再需要编写任何Java 的代码   Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序. 二.跨平台移动开发   Delphi使用android的NDK是通过JNI接口,封装好了,不用自己

如何不用border-radius 写圆角边框

html代码:<div class="items"> <--上面的圆角边框--> <b class="xtop"><b class="xb1"></b><b class="xb2"></b><b class="xb3"></b><b class="xb4"></b

为什么不用C++写游戏(这些工作,QT都替开发者解决了,C++没有根类导致太多的问题,也没有字符串类)

当今世界上绝大多数游戏都是C++写的,为什么要说不呢? 要做什么?写游戏. 写游戏首先要考虑些什么?做什么样的游戏,图形.音效.游戏逻辑如何实现. 用C++要先考虑什么?定义跨平台数据类型抽象,实现常用集合类,设计宏实现RTTI,写一个支持Unicode并可以和其他多种字符串类型互相转换的字符串类,自定义内存分配器,写个shared_ptr,组织预编译头文件,设计实现Object基类以处理跨DLL内存管理等问题…… 那么这些和做游戏有什么关系?不做好这些就很难开始写游戏. 做这些要话多少时间?很

用C++写UI库最本质的思想就是不用C++写UI(如何用 C++ 从零编写 GUI?内含多个开源UI作者的回复,非常精彩)

作者:Bingo链接:https://www.zhihu.com/question/24462113/answer/83371803来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 用C++写UI库最本质的思想就是不用C++「写」UI. 不管是开放C++底层库到XML+Json+Lua的实现,或是单一使用XML完成布局管理,或是现前流行的使用Electron(http://electron.atom.io/)也就是HTML+CSS+JS完成UI实现的,本质上都不希望

EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)

自己写实体可以完美解决这个问题. 用匿名类型也可以. 设置上下文方法如下: (jz为数据库上下文对象) jz.Configuration.ProxyCreationEnabled = false;jz.Configuration.LazyLoadingEnabled = false; 不用这个的原因是Virtual属性也会生成.(只是占个位,[]里面没内容,但看着不爽) 我采用的方法是过滤掉Virtual属性的方法: 一个基于Json.net的类 public class LimitPropsC

你试过不用if写代码吗?

我在教新手编程时,喜欢给他们一些小小的挑战,比如:不使用if语句(或者三元运算符.switch语句等)解决一些编程问题.这样做有什么意义吗?事实上,它可以迫使你从不同的角度寻找解决方法,也许可以找到更好的方法. 正文共:2799 字 预计阅读时间:7 分钟 我在教新手编程时,喜欢给他们一些小小的挑战,比如:不使用if语句(或者三元运算符.switch语句等)解决一些编程问题. 这样做有什么意义吗? 事实上,它可以迫使你从不同的角度寻找解决方法,也许可以找到更好的方法. 当然,使用if语句没有任何

不用ide编译java程序时调用jar包

调用特定目录下的jar包 javac -cp d:\javatest\dom4j.jar Dom4jDemo.java //这部分必须注意,d:\javatest 是Dom4jDemo.class所在的目录,运行时;d:\javatest 必须包括D:\javatest>java -classpath d:\javatest\dom4j.jar;d:\javatest\jaxen.jar;d:\javatest Dom4jDemo(注意jar之后的分号) //如果像下面的写法则会提示未找到Dom

不用IDE,进行struts2开发的简单实例

1.在tomcat的webapp中创建一个WEB工程myapp,具体的文件及路径如下所示: ①/webapp/myapp/login.jsp ②/webapp/myapp/welcom.jsp ③/webapp/myapp/error.jsp ④/webapp/myapp/WEB-INF/web.xml ⑤/webapp/myapp/WEB-INF/classes ⑥/webapp/myapp/WEB-INF/classes/struts.xml ⑦/webapp/myapp/WEB-INF/c