.NET Framework 的 Quirk Version

feiyun0112發表於2014-04-18

今天在CSDN上看到一個帖子 :".net 4.0和4.5不同版本的Uri.ToString行為不同?", 除錯.NET Framework 原始碼發現,是這句程式碼起的作用

internal static bool ShouldUseLegacyV2Quirks
        {
            get
            {
                return UriParser.s_QuirksVersion <= UriParser.UriQuirksVersion.V2;
            }
        }

那這個s_QuirksVersion又是怎麼來的呢,查詢原始碼,發現在靜態建構函式中,有這樣一句

UriParser.s_QuirksVersion = (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5 ? UriParser.UriQuirksVersion.V3 : UriParser.UriQuirksVersion.V2);

原來執行時判斷了程式使用的.NET Framework版本!

那它又是怎麼得到版本資訊的呢?

其實是因為編譯時會將這樣一段資訊加入執行檔案中

[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]

當.NET Framework需要決定使用何種Quirk Version時,會讀取目標程式的TargetFrameworkAttribute,得到它編譯時針對 .NET Framework 的版本。

Assembly entryAssembly = Assembly.GetEntryAssembly();

            TargetFrameworkAttribute[] array = (TargetFrameworkAttribute[])entryAssembly.GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
            Console.WriteLine(array[0].FrameworkName);

我想這樣做的原因可能是為了保證升級.NET Framework版本後,舊程式還能按原有方式執行,而不會被新的行為影響。

有興趣的朋友可以將下列程式碼在不同.NET Framework框架下執行看看。

class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int>() { 1, 2, 3 };
            list.ForEach(i =>
            {
                Console.WriteLine(i);
                if (i < 3) { list.Add(i + 1); }
            });

            Console.ReadLine();
        }
    }

 

相關文章