本篇主要體驗,在存在多個版本程序集的情況下,如何讓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();}}
分別生成強名稱程序集不同版本
□ 生成強名稱的程序集
→刪除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");}}
不同強名稱程序集版本共存
□ 創建某個版本的強名稱程序集
→創建一個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#程序集系列”包括:
參考資料:
http://www.computersciencevideos.org/ created by Jamie King
&是取址運算符,作用是提取一個變量的地址。
比如你定義了一個變量,那麼在編譯時,系統就會在內存中分配一個空間。
而這個空間在內存中的位置就是它的地址。&就提取它的地址。
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語言不錯的教材。
&是取址運算符,作用是提取一個變量的地址。
比如你定義了一個變量,那麼在編譯時,系統就會在內存中分配一個空間。
而這個空間在內存中的位置就是它的地址。&就提取它的地址。
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語言不錯的教材。