今天在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(); } }