I wondered the other day how the C# compiler, csc.exe, decides which version of the runtime to target. Some C# language features are effectively syntactic sugar that is logically translated into other C# which is compiled. But when you target a certain version of the framework, how does the compiler change this code generation? The answer appears to be that it looks at the references that you compile against.
Take this small C# class definition in a file enumerable.cs
yield return 10;
If you compile from the command line using
csc /t:library enumerable.cs
you’ll see that the generated class’s constructor uses CurrentManagedThreadId
If you compile the same file referencing the .NET 4 version of mscorlib.dll (via a reference Assembly on my machine which has 4.5 installed)
csc /t:library /nostdlib /r:”c:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0/mscorlib.dll” enumerable.cs
you’ll see that it references ManagedThreadId
I think it’s rather cool that the C# translation can use different methods from the framework depending on what it expects to find on the target. It can lead to a few interesting and unexpected problems though.