-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a special Numeric structure or INumeric Interface #25058
Comments
I'm pretty sure dotnet/csharplang#164 is going to be the answer for this. |
Could you explain how I do some thing like this with shapes? |
Wouldn't that be doable with just dotnet/csharplang#104? public static TEnum SetFlag<TEnum>(TEnum value, TEnum flag) where TEnum : Enum, struct
=> value | flag; |
I asked for similar lang. feature here |
Based on my c# proposal, I also suggest to add these interfaces: |
@MohammadHamdyGhanem
@yaakov-h's suggestion is better, but off the top of my head you'd make the method take |
As soon as you use any of these things as parameter or return types, you end up boxing all these tiny value types on the heap. Not good for performance. Also, DateTime and decimal are not primitives as far as the type system is concerned. All of that begs the question, what would you do with an instance of |
These Interfaces will make writting generics easier. IPerimative can help you |
But what can you do with |
In fact, I faced situations that need INumeric, and this is the most important. I proposed the other as a general solution "just in case". |
"Just in case" proposals are often considered an antipattern. |
I am interested in numeric constraints so that I can create math classes that can use any numeric data type. For example, to make a Vector3 that can use |
The original proposals of having a However, the issue described here is an issue that we would like to fix some point. We have the same need in the We would probably need a combination of new C# language features, and a built-in "Arthimetic" shape/type-class. /cc @ericstj |
@eerhardt
The purpose of the arith keyword is to tell the compiler at design time that x + y is a valid operation, and to ensure that T must be a numeric data type. At run time, T is known and x + y should execute as normal. |
It came to me now, that we also need to constrain object and dynamic types. maybe something like this:
Or it can be shortened like this: But I think Enum class should be some how marked as arith, so there will be no need for any more casting: |
@MohammadHamdyGhanem I think it would make more sense to call it |
@aaronfranke |
I think this will be solved by dotnet/csharplang#110. See @MattWindsor91's writeup at https://github.com/MattWindsor91/roslyn/blob/master/concepts/docs/csconcepts.md |
I looked at the Int32 structure here: |
@jnm2 , @yaakov-h , @aaronfranke , @eerhardt , @khellang |
@MohammadHamdyGhanem indeed, folks care about this problem very much. It's no coincidence that multiple language proposals show how they intend to help solve this problem. I wasn't around for the initial IArithmetic experiments but my understanding is that an interface and instance methods had both poor performance and bad semantics (because they cannot use operators). For operators you need static interfaces, static interfaces could also solve the performance problem since the JIT could assume an impl based on the T and specialize to optimize away the method call without actually having to box the primitive type. This was alluded to in @MattWindsor91's writeup: https://github.com/MattWindsor91/roslyn/blob/master/concepts/docs/csconcepts.md#static-interface-methods-for-the-clr As mentioned static interfaces require changes in both runtime and frameworks so its less than ideal for reach. I think the current C# proposal for type classes/shapes has much more promise. It has the potential to work with purely compiler features, though we might add some default implementations of the shapes/concepts/whatever-they-get-named in the framework itself to facilitate ease of use and type exchange. I'd highly recommend you look through the type class / shapes issues in CSharpLang. I believe those are good generalizations of this type of problem and have the best chance at getting a solution that can reach to the largest number of C# developers. |
@ericstj |
@yaakov-h |
Closing this. As mentioned in other issues (such as #50647) we are looking into the correct surface area to expose here as part of the This is currently being tracked in our dotnet/designs repo and I've added the initial rough draft of the surface area here: dotnet/designs#205 Further discussion or suggestions should happen there and in future PRs that further refine the proposed surface area. |
Intrinsic numeric types (byte, int, float, ….etc) are structures, so unfortunately, they have no base class that can gather all basic methods and operators!
So I suggest to add a special Numeric structure that can accept numeric values of any type. It should contain the value and the underling type of it, as Object class does. Numeric structure should have the basic arithmetic and logical operators. Or it can be an interace (say INumeric) that all numeric data types implement. This will not break any existing code.
Usage:
Numeric structure (or INumeric Inrerface) can be used in generic methods where T is expected to be a numeric type, to carry out the basic arithmetic and logical operators without writing a dozen if statements for each individual numeric type. Objects doesn't have the basic arithmetic and logical operators and have to be converted to numeric types to work with. For example, I tried to do this but failed:
C# refuses n1.Value + n2.Value because it doesn't know how to add objects. Many if statements are needed to deal with different types of n1 and n2, regarding the larger type to use as the output type. This is a hell of code to something that should be easy and direct if there was a general numeric type that can contain any numeric type.
I face the same situation when I use the base Enum class in any method, because Enum can have any numeric type as an underling type!
I saw similar problem in the source code of Vector, where tons of code lines are repeated just to cover all cases of each numeric type!
Note: If you add the numeric type, C# and VB.net should add a new constraint for generic parameters to be numerics.
where T: numeric
this means T can only be of type Numeric or any intrinsic numeric data types.
So, If this Numeric Type or INumeric Interface exists, one can write
instead of:
and the same when writing generic types that deal with numeric data types only.
This can be extended based on this proposal dotnet/csharplang#1233, I also suggest to add these interfaces:
numeric constraint.
IIntegral: for integer tyoes (byte, sbyte, int, uint, short, ushort, long, ulong)
IFloating: (float, double, decemal)
IValue: (numerics and dates).
ILetiral (Char and string).
IPrimitive (numerics, dates, char, string)
These Interfaces will make writting generics easier. IPerimative can help you
format or parsing or using + operation depending on where T: IPerimative.
Also it can be usefull when defining generic lists and dictionaries that can contain different values. This will make them more specialized than using objects.
The text was updated successfully, but these errors were encountered: