Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
142 views
in Technique[技术] by (71.8m points)

c# - How do generics get compiled by the JIT compiler?

I know that generics are compiled by JIT (like everything else), in contrast to templates that are generated when you compile the code.
The thing is that new generic types can be created in runtime by using reflection.
Which can of course affect the generic's constraints. Which already passed the semantic parser.

Can someone explain how this is handled ? And what exactly happens ?
(Both the code generation and semantic check)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I recommend reading Generics in C#, Java, and C++: A Conversation with Anders Hejlsberg.

Qn 1. How do generics get compiled by the JIT compiler?

From the interview:

Anders Hejlsberg: [...] In the CLR [Common Language Runtime], when you compile List, or any other generic type, it compiles down to IL [Intermediate Language] and metadata just like any normal type. The IL and metadata contains additional information that knows there's a type parameter, of course, but in principle, a generic type compiles just the way that any other type would compile. At runtime, when your application makes its first reference to List, the system looks to see if anyone already asked for List<int>. If not, it feeds into the JIT the IL and metadata for List<T> and the type argument int. The JITer, in the process of JITing the IL, also substitutes the type parameter.

[...]

Now, what we then do is for all type instantiations that are value types—such as List<int>, List<long>, List<double>, List<float>—we create a unique copy of the executable native code. So List<int> gets its own code. List<long> gets its own code. List<float>gets its own code. For all reference types we share the code, because they are representationally identical. It's just pointers.


Qn 2. The thing is that new generic types can be created in runtime by using reflection. Which can of course affect the generic's constraints. Which already passed the semantic parser. Can someone explain how this is handled?

Essentially, IL retains a high-level view of generic types, which allows the CLR to check constraints for 'dynamically constructed' generic types at run-time just like the C# compiler might do for 'statically constructed' types in C# source-code at compile-time.

Here's another snippet (emphasis mine):

Anders Hejlsberg: [...] With a constraint, you can hoist that dynamic check out of your code and have it be verifiable at compile time or load time. When you say K must implement IComparable, a couple of things happen. On any value of type K, you can now directly access the interface methods without a cast, because semantically in the program it's guaranteed that it will implement that interface. Whenever you try and create an instantiation of that type, the compiler will check that any type you give as the K argument implements IComparable, or else you get a compile time error. Or if you're doing it with reflection you get an exception.

Bruce Eckel: You said the compiler and the runtime.

Anders Hejlsberg: The compiler checks it, but you could also be doing it at runtime with reflection, and then the system checks it. As I said before, anything you can do at compile time, you can also do at runtime with reflection.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...