❔ Specializing a Generic?

If I make a MyClass<T>, can I make a, for example, couple specializations like MyClass<int> and MyClass<double> implementing some specific behaviour?
34 Replies
Angius
Angius2y ago
You can have MyClassInt : MyClass<int> and MyClassDouble : MyClass<double> for example
LordKalma (CT7ALW)
Bah, I was looking for something more akin to C++'s template specializations, where you could still have the MyClass<T> syntax and magically use different implementations
Thinker
Thinker2y ago
The point of generics is to have a single implementation for multiple types You can kind of do the specializations thing though using if (typeof(T) == typeof(int)) and running a specialized variant if that's the case Really depends on why you'd want these kinds of specializations
LordKalma (CT7ALW)
yeah, I don't want to add branching to this code... it was for style of API like if you have a float precision FFT and a double precision FFT writing FloatFft and DoubleFft lacks the swag of Fft<float> and Ffr<double> (before you ask, the implementation could be different in terms of optimizations and SIMD especially)
Thinker
Thinker2y ago
ah Probably a better question for #allow-unsafe-blocks
LordKalma (CT7ALW)
That's when I actually craft the internals :p I was just curious about whether I could do an API like that
Thinker
Thinker2y ago
However if you want to generalize over specifically numeric types then INumber<T> and a couple related interfaces exist.
LordKalma (CT7ALW)
I'll research about that, thanks
Thinker
Thinker2y ago
Also you could maybeee do the generic specialization thing using source generation/MSBuild tasks/IL weaving black magic, but it's not an inherent language feature, and it'd be a lot of work and you have to jump through a ton of hoops in order to get it to work.
LordKalma (CT7ALW)
Yeah, I just wanted a stylish API, which is NOT worth the effort hehe
Aaron
Aaron2y ago
that example wouldn't branch the JIT is smart enough to realize that T is or is not int when compiling the method
LordKalma (CT7ALW)
You reckon the compiler would yeet that?
Aaron
Aaron2y ago
the JIT would, yes the BCL makes use of that pattern all over the place
reflectronic
reflectronic2y ago
can you use generic math instead it seems like you want where T : IBinaryFloatingPointIeee754<T>, and then you can just do the math without writing specializations yourself
LordKalma (CT7ALW)
for starters, C# doesn't even have a float complex type, for some reason only double and we're talking possible SIMD methods and etc there's also the AoT to be concerned about :p that's why I said "compiler"
Aaron
Aaron2y ago
AOT would do the same
LordKalma (CT7ALW)
yes, I figured but oh well
Aaron
Aaron2y ago
you can also check availability for SIMD methods at compile time, if you'd like with Vector<T>.IsSupported
reflectronic
reflectronic2y ago
you may want to leave a comment showing interest in Complex<T>, then https://github.com/dotnet/runtime/issues/80665
GitHub
[API Proposal]: Expand Complex Number support · Issue #80665 · dotn...
Background and motivation The current implementation of Complex in System.Numerics feels like a second-class citizen; it cannot be easily used in similar ways to other numeric types, and as it is b...
reflectronic
reflectronic2y ago
i know it doesn't help today, but requests from users matter a lot when they are planning out what work to do in the future
LordKalma (CT7ALW)
I will confirm on linqpad, but if the compiler can just remove the indirection of an if (typeof(T) == typeof(int)) or a switch case on types with pattern matching, then it's accepteable
LordKalma (CT7ALW)
I'll definitely leave a comment for support good! if I put the implementation on a different method, I hope it also removes the call indirection, which it probably ought to
reflectronic
reflectronic2y ago
yes, though you may need the AggressiveInlining like the example I showed, the compiler might hesitate because of the IL size
LordKalma (CT7ALW)
The implementation methods could use some [MethodImpl(MethodImplOptions.AggressiveInlining)] haha exactly
Thinker
Thinker2y ago
Is there any reason it's using return left.CompareTo(right) < 0 ? true : false; instead of just return left.CompareTo(right) > 0;?
reflectronic
reflectronic2y ago
it's a performance hack
Thinker
Thinker2y ago
kind of suspected that
Anton
Anton2y ago
Nope. The closest thing would be caching types to instantiate or instances in a dictionary by the type as the key, and presetting the few derived classes like shown above.
LordKalma (CT7ALW)
I understand those words if they are not together. Want to explain? ah interesting
reflectronic
reflectronic2y ago
the specializing trick doesn't work for reference types
canton7
canton72y ago
Yeah. It's because the JIT emits a specialised version for each value type the generic is used with (value types are different sizes, after all), but one version for all reference types (it effectively does java-style type erasure here)
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server