程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#程序集系列13,如何讓CLR選擇不同版本的程序集,

C#程序集系列13,如何讓CLR選擇不同版本的程序集,

編輯:C#入門知識

C#程序集系列13,如何讓CLR選擇不同版本的程序集,



本篇主要體驗,在存在多個版本程序集的情況下,如何讓CLR選擇哪個版本程序集運行,以及程序集版本的切換。

 

 

  分別生成非強名稱程序集不同版本

□ 生成某個版本的程序集

→清理F盤as文件夾,剩下如下文件

→查看Cow.cs文件

using System;
using System.Reflection;
[assembly: AssemblyVersion("3.3.3.3")]
public class Cow
{
    public static void Moo()
    {
        Console.WriteLine("Moo version 1");
    }
}


→編譯Cow.cs,生成Farm.dll程序集

注意:Farm.dll還不是強名稱程序集
→編譯MainClass.cs文件,生成可執行文件,引用Farm.dll

→運行MainClass.exe

 

□ 生成另一個版本的程序集

→修改Cow.cs文件,保存

using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class Cow
{
    public static void Moo()
    {
        Console.WriteLine("Moo version 2");
    }
}

→重新編譯Cow.cs,重新生成Farm.dll

→再次運行MainClass.exe

第二次生成的Farm.dll已經生效。

→修改Cow.cs中的類名為BigCow,保存

using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class BigCow
{
    public static void Moo()
    {
        Console.WriteLine("Moo version 2");
    }
}

→MainClass.cs中的內容如下

using System;
class MainClass
{
    static void Main()
    {
        Cow.Moo();
    }
}

→再次編譯Cow.cs,再次生成Farm.dll

→再次運行MainClass.exe,發現報錯了

因為在MainClass.cs中,視圖找Cow,但已經不存在,已經變成了BigCow。


 

  分別生成強名稱程序集不同版本

□ 生成強名稱的程序集

→刪除Farm.dll和MainClass.exe

→再次把Cow.cs修改為如下,保存

using System;
using System.Reflection;
[assembly: AssemblyVersion("3.3.3.3")]
public class Cow
{
    public static void Moo()
    {
        Console.WriteLine("Moo version 1");
    }
}

→重新編譯Cow.cs,這次使用密匙

→再次編譯MainClass.cs

→再次運行MainClass.exe

 

□ 生成強名稱的另外一個程序集

→修改Cow.cs如下,改變版本和方法實現

using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class Cow
{
    public static void Moo()
    {
        Console.WriteLine("Moo version 2");
    }
}

→再次編譯Cow.cs,但用以上次同樣的密匙

→運行MainClass.exe,報錯

說明主程序不能找到第一個版本的強名稱程序集。

 

  不同強名稱程序集版本共存

□ 創建某個版本的強名稱程序集

→創建一個Farm文件夾

→再次修改Cow.cs,修改成第一個版本,保存

using System;
using System.Reflection;
[assembly: AssemblyVersion("3.3.3.3")]
public class Cow
{
    public static void Moo()
    {
        Console.WriteLine("Moo version 1");
    }
}

→編譯Cow.cs,重新生成Farm.dll

→運行MainClass.exe

說明,當程序集變成第一個版本的強名稱程序集,程序又可以正常運行。
→把Farm.dll移動到Farm文件夾中

→運行MainClass.exe,因為已經在MainClass.exe.config中自定義了CLR運行時查找程序集的方式,所以運行正常

 

□ 創建另一個版本的強名稱程序集

→再次修改Cow.cs到第二個版本,保存

using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class Cow
{
    public static void Moo()
    {
        Console.WriteLine("Moo version 2");
    }
}


→編譯Cow.cs

注意:此時,在Farm文件中還有一個Farm.dll,是第一個版本。
→運行MainClass.exe,再次報錯

現在的問題是:有2個版本的Farm.dll,CLR運行時無法決定采用哪個版本的Farm.dll.不過,可以先記下這裡的PublicKeyToken:863de8402b3a9978

 

  告訴CLR執行哪個版本的強名稱程序集

現在同時有了2個Farm.dll,如何讓CLR決定指定哪個版本呢?
--需要在MainClass.exe.config中設置

 

→假設,我們需要使用Farm文件夾中的Farm.dll程序集,設置如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Farm" publicKeyToken="863de8402b3a9978" />
                <bindingRedirect oldVersion="3.3.3.3" newVersion="8.8.8.8" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

→再次運行MainClass.exe

一切正常。

 

  使用舊版本的強名稱程序集

→修改MainClass.exe.config中設置如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Farm" publicKeyToken="863de8402b3a9978" />
                <bindingRedirect oldVersion="8.8.8.8" newVersion="3.3.3.3" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

→把as文件夾下的Farm.dll刪除,把as下的Farm文件夾中的Farm.dll移動到as下
→再次運行MainClass.exe

一切正常,已經在使用舊版本的強名稱程序集

 

總結:
○ 如果想讓CLR選擇哪個版本的程序集運行,該程序集必須是強名稱程序集
○ 版本的切換在"可執行文件名稱.exe.config"中設置

 

“C#程序集系列”包括:

  C#程序集系列01,用記事本編寫C#,IL代碼,用DOS命令編譯程序集,運行程序

  C#程序集系列02,使用記事本查看可執行程序集的IL代碼

  C#程序集系列03,引用多個module

  C#程序集系列04,在程序集包含多個module的場景下理解關鍵字internal

  C#程序集系列05,讓程序集包含多個module

  C#程序集系列06,程序集清單,EXE和DLL的區別

  C#程序集系列07,篡改程序集

  C#程序集系列08,設置程序集版本

  C#程序集系列09,程序集簽名

  C#程序集系列10,強名稱程序集

  C#程序集系列11,全局程序集緩存

  C#程序集系列12,C#編譯器和CLR如何找尋程序集

  C#程序集系列13,如何讓CLR選擇不同版本的程序集

 

參考資料:

http://www.computersciencevideos.org/  created by Jamie King

 

 

 


C語言&& || !分別是什

&是取址運算符,作用是提取一個變量的地址。
比如你定義了一個變量,那麼在編譯時,系統就會在內存中分配一個空間。
而這個空間在內存中的位置就是它的地址。&就提取它的地址。
e.g int a;在編譯時就給它分配一個地址,比如是2000;&a就是2000。
假如先定義了一個整型指針變量p,p=&a;就是把a的地址2000賦給p。運行後p=2000。
又如scanf("%d",&a);當你輸入3時,它會先根據&a知道a的地址,由地址找到a在內存中的空間,再把3寫入這個空間。
*是指針運算符,作用與&相反,它是根據變量的地址取出變量的值。
比如,*a的值就是變量a的值3。
下面是定義和聲明中用到指針的小結
int *p; 定義一個指向整型數據的指針。
int *p[n]; 定義指針數組p,它由n個指向整型數據的指針元素組成。
int (*p)[n]; p為指向含n個元素的一維數組的指針變量。
int *p(); p為返回一個指針的函數,該指針指向整型數據。
int (*p)(); p為指向函數的指針,該函數返回一個整型值
int **p; p是一個指針變量,它指向一個指向整型數據的指針變量。
如果你想系統的了解建議你可以看看譚浩強的《c程序設計》(第三版)這本書通俗易懂。是學習c語言不錯的教材。
 

C語言&& || !分別是什

&是取址運算符,作用是提取一個變量的地址。
比如你定義了一個變量,那麼在編譯時,系統就會在內存中分配一個空間。
而這個空間在內存中的位置就是它的地址。&就提取它的地址。
e.g int a;在編譯時就給它分配一個地址,比如是2000;&a就是2000。
假如先定義了一個整型指針變量p,p=&a;就是把a的地址2000賦給p。運行後p=2000。
又如scanf("%d",&a);當你輸入3時,它會先根據&a知道a的地址,由地址找到a在內存中的空間,再把3寫入這個空間。
*是指針運算符,作用與&相反,它是根據變量的地址取出變量的值。
比如,*a的值就是變量a的值3。
下面是定義和聲明中用到指針的小結
int *p; 定義一個指向整型數據的指針。
int *p[n]; 定義指針數組p,它由n個指向整型數據的指針元素組成。
int (*p)[n]; p為指向含n個元素的一維數組的指針變量。
int *p(); p為返回一個指針的函數,該指針指向整型數據。
int (*p)(); p為指向函數的指針,該函數返回一個整型值
int **p; p是一個指針變量,它指向一個指向整型數據的指針變量。
如果你想系統的了解建議你可以看看譚浩強的《c程序設計》(第三版)這本書通俗易懂。是學習c語言不錯的教材。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved