❔ 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
You can have
MyClassInt : MyClass<int>
and MyClassDouble : MyClass<double>
for exampleBah, 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 implementationsThe 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 specializationsyeah, 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)ah
Probably a better question for #allow-unsafe-blocks
That's when I actually craft the internals :p
I was just curious about whether I could do an API like that
However if you want to generalize over specifically numeric types then
INumber<T>
and a couple related interfaces exist.I'll research about that, thanks
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.
Yeah, I just wanted a stylish API, which is NOT worth the effort hehe
that example wouldn't branch
the JIT is smart enough to realize that T is or is not int when compiling the method
You reckon the compiler would yeet that?
the JIT would, yes
the BCL makes use of that pattern all over the place
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 yourselffor 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"
AOT would do the same
yes, I figured
but oh well
you can also check availability for SIMD methods at compile time, if you'd like
with
Vector<T>.IsSupported
you may want to leave a comment showing interest in
Complex<T>
, then https://github.com/dotnet/runtime/issues/80665GitHub
[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...
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
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 accepteableit will for sure, the same pattern is used in the runtime in a number of places, e.g. here it's used in Array.Sort https://github.com/dotnet/runtime/blob/b2fa5bdeb3bab8e21524c162fb9042030ae1ac9d/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs#L565-L582
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
yes, though you may need the AggressiveInlining like the example I showed, the compiler might hesitate because of the IL size
The implementation methods could use some
[MethodImpl(MethodImplOptions.AggressiveInlining)]
haha exactlyIs there any reason it's using
return left.CompareTo(right) < 0 ? true : false;
instead of just return left.CompareTo(right) > 0;
?it's a performance hack
kind of suspected that
Will do that
Ths generated an interesting discussion
https://github.com/dotnet/csharplang/discussions/1315#discussioncomment-5659558
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.
I understand those words if they are not together. Want to explain?
ah interesting
the specializing trick doesn't work for reference types
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)
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.