简体   繁体   中英

C# generics implementation

I am new to C# and was trying to write an SNTP server on the weekend. During the course of this development I ended up with exactly the same question as this one: How to use generics to pass argument to a non-generic method?

The question, repeated here is: "How to use generics to pass argument to a non-generic method?" The crucial answer to this question was that the non-generic method in question didn't have an overload which accepted an Object.

Now the question I have is a follow on question: why is Generics implemented this way? Or to rephrase, why are constraints required at all?

My understanding so far is that generics help to preserve compile time type safety which means that the compiler knows what types are being dealt with at compile time.

Why wasn't C# (or perhaps this question should pertain to the CLR) implemented such that the compiler can accept the fact that a generic class/method is being created in which an argument can be provided which may not be acceptable in all cases. Then, when the generic class/method get's invoked, the compiler can see the issue and complain at that time .

Is this a technical limitation?

It just seems like a real pity that a generic method cannot be created to wrap a non generic method with multiple overloads. Unless I opt to defer type checking to run time which is the solution to the aforementioned question, I would have to wrap this overloaded method with a suite of methods, one for each signature, even though the code within it will look identical. This would have been an ideal place to leverage a generic method.

The person who can best explain this is Eric Lippert, and he did, in What's the difference, part one: Generics are not templates :

We do the overload resolution once and bake in the result. We do not change it at runtime when someone, possibly in an entirely different assembly, uses string as a type argument to the method. The IL we've generated for the generic type already has the method its going to call picked out. The jitter does not say “well, I happen to know that if we asked the C# compiler to execute right now with this additional information then it would have picked a different overload. Let me rewrite the generated code to ignore the code that the C# compiler originally generated...” The jitter knows nothing about the rules of C#.

[...]

Now, if you do want overload resolution to be re-executed at runtime based on the runtime types of the arguments, we can do that for you; that's what the new “dynamic” feature does in C# 4.0. Just replace “object” with “dynamic” and when you make a call involving that object, we'll run the overload resolution algorithm at runtime and dynamically spit code that calls the method that the compiler would have picked, had it known all the runtime types at compile time.

So why not: because the runtime wouldn't know how to re-generate the required code.

And something about a design philosophy that your code should fail as early as possible, preferably during compile time, but I can't find that quote right now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM