zoukankan      html  css  js  c++  java
  • 《CLR Via C# 第3版》笔记之(三) 程序集和模块

    主要内容:

    • 程序集和模块区别
    • 多文件程序集

    1. 程序集和模块区别

    关于.net中程序集和模块的区别,其实已经有很多人讨论过了,希望本篇仍对大家有所帮助。

    程序集与模块的共同点:

    1. 都是为了定义一些可重用的类型。
    2. 对于引用者来说,调用程序集中的公开类型(public)和模块的公开类型,没有什么分别。

    程序集和模块的区别:(主要是程序集包含的内容更加丰富)

    1. 程序集可以发布,而模块不能。
    2. 程序集标记了一个版本号,可以唯一的标记程序集。
    3. 程序集还可以包含有关联的安全信息。

    以下演示编译程序集和模块的方法:

    首先定义两个文件,MyAssembly.cs和MyModule.cs。

    using System;
    
    namespace CLRViaCSharp
    {
        public class MyAssembly
        {
            public MyAssembly()
            { }
    
            public void Public_method()
            {
                Console.WriteLine("this is a public method!");
            }
    
            protected void Protected_method()
            {
                Console.WriteLine("this is a protected method!");
            }
    
            private void Private_method()
            {
                Console.WriteLine("this is a private method!");
            }
        }
    }
    
    using System;
    
    namespace CLRViaCSharp
    {
        public class MyModule
        {
            public MyModule() { }
    
            public void Public_method()
            {
                Console.WriteLine("this is a public method!");
            }
    
            protected void Protected_method()
            {
                Console.WriteLine("this is a protected method!");
            }
    
            private void Private_method()
            {
                Console.WriteLine("this is a private method!");
            }
        }
    }
    

    分别编译为assembly和module。

    d:\Vim\csharp>csc /t:library /out:MyAssembly.dll MyAssembly.cs
    Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    
    d:\Vim\csharp>csc /t:module /out:MyModule.netmodule MyModule.cs
    Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.

    生成的程序集和模块分别为:MyAssembly.dll,MyModule.netmodule。生成后使用ILDASM.exe分别来查看其元数据。查看方法:ILDASM | View | MetaInfo | Show!

    比较MyAssembly.dll和MyModule.netmodule的元数据,我们发现MyAssembly.dll明显多了以下信息。

    Assembly
    -------------------------------------------------------
    	Token: 0x20000001
    	Name : MyAssembly
    	Public Key    :
    	Hash Algorithm : 0x00008004
    	Version: 0.0.0.0
    	Major Version: 0x00000000
    	Minor Version: 0x00000000
    	Build Number: 0x00000000
    	Revision Number: 0x00000000
    	Locale: <null>
    	Flags : [none] (00000000)
    	CustomAttribute #1 (0c000001)
    	-------------------------------------------------------
    		CustomAttribute Type: 0a000001
    		CustomAttributeName: System.Runtime.CompilerServices.CompilationRelaxationsAttribute :: instance void .ctor(int32)
    		Length: 8
    		Value : 01 00 08 00 00 00 00 00                          >                <
    		ctor args: (8)
    
    	CustomAttribute #2 (0c000002)
    	-------------------------------------------------------
    		CustomAttribute Type: 0a000002
    		CustomAttributeName: System.Runtime.CompilerServices.RuntimeCompatibilityAttribute :: instance void .ctor()
    		Length: 30
    		Value : 01 00 01 00 54 02 16 57  72 61 70 4e 6f 6e 45 78 >    T  WrapNonEx<
                          : 63 65 70 74 69 6f 6e 54  68 72 6f 77 73 01       >ceptionThrows   <
    		ctor args: ()
    

    即表明MyAssembly.dll为一个程序集。正因为有了这些信息,MyAssembly.dll才可以发布和部署。

    2. 多文件程序集

    一般我们自己编译的程序集都是单个文件的(一个exe或者一个dll)。那么,如何编译出多文件的程序集呢?

    多文件的程序集有以下的优势:

    1. 发布后,程序集有多个文件,只须下载所需的文件就能运行程序集,不用全部下载。
    2. 发布后,如果程序集有更新,只须下载更新的部分即可,不用重新下载整个程序集。

    下面进行简单的实验

    首先,建立3个文件,Module1.cs, Module2.cs, Program.cs。内容如下:

    // file:Module1.cs
    
    using System;
    
    namespace CLRViaCSharp
    {
        public class Module1
        {
            public void Module1_method()
            {
                Console.WriteLine("this is the original module1");
            }
        }
    }
    
    // file:Module2.cs
    
    using System;
    
    namespace CLRViaCSharp
    {
        public class Module2
        {
            public void Module2_method()
            {
                Console.WriteLine("this is the original module2");
            }
        }
    }
    
    
    // file :Program.cs
    
    using System;
    
    namespace CLRViaCSharp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Module1 m1 = new Module1();
                Module2 m2 = new Module2();
    
                m1.Module1_method();
                m2.Module2_method();
            }
        }
    }

    然后,分别将Module1.cs和Module2.cs编译为模块,将此两个模块和Program.cs编译为一个程序集。

    D:\Vim\csharp>csc /t:module Module1.cs
    Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    
    D:\Vim\csharp>csc /t:module Module2.cs
    Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    
    D:\Vim\csharp>al /t:library /out:Module.dll Module1.netmodule Module2.netmodule
    Microsoft (R) Assembly Linker version 10.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    
    D:\Vim\csharp>csc Program.cs /r:Module.dll
    Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.

    注意其中第三步是用来al.exe这个程序集链接器来链接dll的。

    执行编译好的Program.exe,结果如下:

    D:\Vim\csharp>Program.exe
    this is the original module1
    this is the original module2

    然后我们修改一下Module1.cs文件,修改Console.WriteLine的内容。

    using System;
    
    namespace CLRViaCSharp
    {
        public class Module1
        {
            public void Module1_method()
            {
                Console.WriteLine("this is the update module1");
            }
        }
    }
    

    只重新编译一下Module1.cs,注意此处不重新编译Module.dll和Program.exe

    再次执行Program.exe时,结果就改变了。

    D:\Vim\csharp>csc /t:module Module1.cs
    Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    
    D:\Vim\csharp>Program.exe
    this is the update module1
    this is the original module2

    这个例子中的Module.dll就是个多文件的程序集,它并没有将Module1.netmodule和Module2.netmodule的内容加到Module.dll中,只是在Module.dll中保存了Module1.netmodule和Module2.netmodule的引用。

    查看Module.dll的元数据也可以看出这点,Module.dll中只有清单(Manifest),没有实际的IL内容。

    捕获

  • 相关阅读:
    [Luogu P3626] [APIO2009] 会议中心
    杭电 1869 六度分离 (求每两个节点间的距离)
    杭电 1874 畅通工程续 (求某节点到某节点的最短路径)
    最短路径模板
    杭电 2544 最短路径
    POJ 1287 Networking (最小生成树模板题)
    NYOJ 1875 畅通工程再续 (无节点间距离求最小生成树)
    POJ 2485 Highways (求最小生成树中最大的边)
    杭电 1233 还是畅通工程 (最小生成树)
    杭电 1863 畅通工程 (最小生成树)
  • 原文地址:https://www.cnblogs.com/wang_yb/p/2026530.html
Copyright © 2011-2022 走看看