Why is there no base Number type in C #?

Unlike java, why does C # have no supertype Number for Floats, Integer, etc.? Any arguments for excluding a number in C #?

+6
c #
source share
6 answers

I do not know if it is true, but one explanation that I heard was weighty - in particular, for small frameworks (Compact Framework, Silverlight, Micro Framework); I'm not sure about that ...

Much more convincing is that it is known in itself that this number does not provide much; for example, integer division works differently with floating point, and the operators are not always as simple as you would like (think DateTime + TimeSpan => DateTime , DateTime - DateTime => TimeSpan ).

If this helps, MiscUtil offers general operator support , allowing things like:

 T x = ..., y = ...; // any T that has suitable operators T sum = Operator.Add(x,y); 

Everything is very clean and efficient. Please note, however, that there is no compilation time check (since there are no suitable general restrictions). But it works.

+4
source share

Because value types cannot be inherited.

+6
source share

This may have performance reasons . Numbers that are struct types are stacked quickly and do not allow inheritance structures. Using them in an OO-way will require a very large amount of auto / unpacking and, in addition, a large decrease in performance due to a much larger memory consumption and vtable search for polymorphism.

Java has implemented object-oriented wrappers and ends with different and incompatible implementations for the same thing with even stranger things.

The best way to provide quick abstractions for numbers would be to introduce typeclasses / concepts, for example, in Haskell or C ++, where you could write:

 sum :: (Num t) => [t] -> t 

read how Sum takes a list of elements of type t - where t is a numeric type - and returns that number. This mechanism could be optimized at compile time without any overhead. But neither .NET nor Java have such methods.

+3
source share

But it would be very useful if they turned it on, it would be for all integer numeric types (int, short, long, uint, etc.) that were defined to implement an empty interface named IIntegral , and all numeric (Integral plus decimal , float, etc.) that were defined to implement an empty interface named INumeric .

This would allow generics to set constraints based on these interfaces to limit valid types of integral types or numeric types, which is currently a much more complex problem.

+1
source share

ValueType is pretty close. There are not many types of values โ€‹โ€‹that cannot be represented as a single number:

  static void Main(string[] args) { int myInteger = 42; decimal myDecimal = 3.141592653589793238M; long myLong = 900000000000; byte myByte = 128; float myFloat = 2.71828F; TestFunction(myInteger); TestFunction(myDecimal); TestFunction(myLong); TestFunction(myByte); TestFunction(myFloat); } static void TestFunction(System.ValueType number) { Console.WriteLine(number.ToString()); } 

Output:

  • 42
  • +3.141592653589793238
  • 900000000000
  • 128
  • 2.71828
+1
source share

You can create an extension for Object that returns a bool for you, for example (untested, can provide false positives, etc.) (catches decimal numbers, float, ints, using the US style delimiter for a decimal number, modifies the regular expression to match hex , etc.)

 public static class Object { static Regex r = new Regex(@"^\d*\.*\d$", RegexOptions.Compiled); public static bool IsNumber(this object obj) { return r.IsMatch(obj.ToString() && !(obj is string); } } 

Since ToString is part of Object, and everything is ultimately a child of the object ...

Of course, this will not provide security such as generics or something like that, but it will still allow you to do such things with a little more work. You did not indicate what the base class is for, whether you want to accept a numeric type as an argument somewhere, or if you need generics. This can lead you to participate anywhere you go.

Using:

 public class thingThatHasNumericValue { private object arbNumber; public object SomeArbitraryNumber { get { return arbNumber; } set { if (!arbNumber.IsNumber()) { throw new InvalidOperationException("Must be a number"); } arbNumber = value; } } } 
0
source share

All Articles