Test Program
Let's take a look at the very simple C # program tester. CS below:
1 Using System; 2 3 Static Class Tester 4 { 5 Static Void Main () 6 { 7 Console. writeline ( " CLR: " + Environment. version ); 8 Console. writeline ( " Concat: " + String . Concat ( New Int [] { 12 , 345 })); 9 } 10 }
The actual content of this test program is only one row, that is, 8th rows. The static method Concat of the string class is called.
Running result
Let's take a look at the running results of the above test program. The first is the mono environment of the Linux operating system:
Ben @ vbox :~ /Work>GMCs tester. CS & mono tester.exeCLR: 2.0.50727.1433concat:System. int32 []Ben @ vbox :~ /Work>DMCS tester. CS & mono tester.exeCLR: 4.0.30319.1concat:12345
Microsoft. NET Framework environment for Windows:
D: \ work>C: \ windows \ Microsoft. NET \ framework \ v2.0.50727 \ csc.exe tester. CSMicrosoft (r) Visual C #2005 compiler version 8.00.50727.4016 is used for Microsoft (r) Windows (r) 2005 Framework Version 2.0.50727 copyright (c) Microsoft Corporation 2001-2005. All rights reserved. D: \ work>Tester.exeCLR: 2.0.50727.4216concat:System. int32 []D: \ work>C: \ windows \ Microsoft. NET \ framework \ v4.0.30319 \ csc.exe tester. CSMicrosoft (r) Visual C #2010 compiler 4.0.30319.1 copyright (c) Microsoft Corporation. All rights reserved. D: \ work>Tester.exeCLR: 4.0.30319.276concat:12345
As you can see, the same C # program, whether it is a Linux operating system or a Windows operating system, shows incompatibility between. NET Framework 2.0 and. NET Framework 4.
Analysis
The above running result is mainly because the static method Concat of the string class has nine overloaded versions in. NET Framework 2.0, and there are 11 overloaded versions in. NET Framework 4. The actual version of the C # program called for the above test is as follows:
. NET Framework 2.0: public static string Concat (Object arg0). Net Framework 4: Public static string Concat <t> (ienumerable <t> values)
It seems that adding new methods to the. NET Framework base class library is not safe, and may change the behavior of the original C # program. This reminds us to extract the original program from. net Framework 2.0. NET framework 4 should be careful during migration, not only to note that the "version considerations" are clearly stated in msdn, but also to pay attention to this subtle change.
View Il Code
Run the following command in Linux to decompile tester.exe as ilasm.Source codeFile:
Ben @ vbox :~ /Work>GMCs tester. CS & monodis tester.exe> Tester-v2.ilBen @ vbox :~ /Work>DMCS tester. CS & monodis tester.exe> Tester-v4.il
Below is the Tester-v2.il file:
1 . Assembly Extern Mscorlib 2 { 3 . Ver 2 : 0 : 0 : 0 4 . Publickeytoken = (B7 7A 5C 56 19 34 E0 89 )// . Z \ v.4 .. 5 } 6 . Assembly ' Tester ' 7 { 8 . Custom Instance Void Class [Mscorlib] system. runtime. compilerservices. runtimecompatibilityattribute ::' . Ctor ' () = ( 9 01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78 // ... T... wrapnonex 10 63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01 ) // Ceptionthrows. 11 12 . Hash Algorithm Zero X 00008004 13 . Ver 0 : 0 : 0 : 0 14 } 15 . Module Tester.exe // Guid = {9f6a8c8f-b962-4e6a-a4e9-fa6ff9e83982} 16 17 18 . Class Private Auto ANSI Abstract sealed Beforefieldinit Tester 19 Extends [Mscorlib] system. Object 20 { 21 22 // Method Line 1 23 . Method Private Static Hidebysig 24 Default Void Main () Cel Managed 25 { 26 // Method begins at RVA 0x20ec 27 . Entrypoint 28 // Code size 60 (0x3c) 29 . Maxstack 8 30 Il_0000: Ldstr " CLR: " 31 Il_0005: Call Class [Mscorlib] system. Version Class [Mscorlib] system. Environment: get_version () 32 Il_000a: Call String String : Concat ( Object , Object ) 33 Il_000f: Call Void Class [Mscorlib] system. Console: writeline ( String ) 34 Il_0014: Ldstr " Concat: " 35 Il_0019: LDC. i4.2 36 Il_001a: Newarr [Mscorlib] system. int32 37 Il_001f: DUP 38 Il_0020: LDC. i4.0 39 Il_0021: LDC. i4.s 0x0c 40 Il_0023: Stelem. I4 41 Il_0024: DUP 42 Il_0025: LDC. i4.1 43 Il_0026: LDC. I4 345 44 Il_002b: Stelem. I4 45 Il_002c: Call String String : Concat ( Object ) 46 Il_0031: Call String String : Concat ( String , String ) 47 Il_0036: Call Void Class [Mscorlib] system. Console: writeline ( String ) 48 Il_003b: RET 49 } // End of method Tester: Main 50 51 } // End of class Tester
Use the diff command to look at the differences between Tester-v4.il and Tester-v2.il:
Ben @ vbox :~ /Work>Diff Tester-v2.il Tester-v4.il3c3<. Ver2: 0: 0: 0--->. Ver4: 0: 0: 015c15<. Module tester.exe // guid = {9f6a8c8f-b962-4e6a-a4e9-fa6ff9e83982} --->. Module tester.exe // guid = {D564CE72-73D3-43DD-B6F4-FB12809D5589}45c45<Il_002c: Call string: Concat (Object) ---> Il_002c: Call string: Concat<Int32>(Class [mscorlib] system. Collections. Generic. ienumerable '1 <!! 0>)
We can see that there are only three differences in total:
- Different lines 3rd indicate different. NET Framework versions.
- The differences in rows 15th only indicate that different tester.exe guids are different.
- The differences in row 45th indicate that the overloaded version of the called Concat method is different.
The differences between the above 3rd points validate our analysis in the previous section and clearly show the different overloaded versions of the Concat method called accordingly.
References
- Msdn: String. Concat method (system)
- Msdn: String. Concat method (object) (system)
- Msdn: String. Concat (t) method (ienumerable (t) (system)