3 ms·
> Another example: while C# has polymorphized generics, it checks them at compile time! The generics are not monomorphized like C++ or Rust, which allows smalle
by neonsunset 2y ago
> Another example: while C# has polymorphized generics, it checks them at compile time! The generics are not monomorphized like C++ or Rust, which allows smaller linked libraries that you can load and use at runtime, which is not possible in C++ templates or Rust generics. The trade-off is then that generics can't be checked until runtime - but actually no. The C# compiler will go out of its way to check generics when it can and will fail if they don't meet the type constraints, just like C++ or Rust.
Generics are not monomorphized at bytecode level, but whenever generic argument is a struct, the methods and types that have it are monomorphized at the stage of compiling to machine code, be it with JIT or ILC. This is identical to Rust, and is why C# has "zero-cost" abstractions.
Method bodies and types for class-type generic arguments are indeed shared however. Dispatch on generic constraints is still quite efficient in that case, even if no longer zero-cost (unless the compiler is able to see the exact type and inline such calls, or emit a guarded devirtualized fast-path when compiled by JIT, or prove that only few types implement a particular interface or subclass a specific parent when compiled by NativeAOT).