tags:

views:

215

answers:

7

Unlike in java why c# does not have a supertype of Number for Floats, Integers etc? Any reasoning behind avoiding Number in c#?

+5  A: 

Because value types can't be inherited.

Fujiy
Value types can inherit - every enum inherits from System.Enum.
Daniel Brückner
It could have implemented an interface... by itself, I'm not sure that this is a satisfying answer.
Marc Gravell
Daniel, Enum are specials in C#. And it is a class:public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible
Fujiy
+2  A: 

what would you need that for?

Johannes Rudolph
Creating generic classes that accept only numeric types.
JoshJordan
Do all the number types support the same opcodes? If so then maybe they could support generics with a new keywork (like "where T: numeric") instead of changing the object hierarchy of the numeric types.
ChrisW
Numbers were added to the language long, long before generics were.
Greg D
+1  A: 

But very useful, if they had included it, would have been for all integral numeric types (int, short, long, uint, etc.) to have been defined to implement an empty interface named IIntegral, and all numeric types (Integral plus decimal, float, etc.), to have been defined to implement an empty interface named INumeric.

This would have allowed generics to have specified constraints based on these interfaces to restrict allowable types to the integral types, or to numeric types, which is currently a much more difficult problem.

Charles Bretana
+3  A: 

It might have performance reasons - Numbers, being struct-types, are stack-allocated and fast but do not allow inheritance structures. Using them in an OO-way would require a very large amount of auto/unboxing and additionally big much performance reductions due to much more memory consumption and vtable lookups to solve the polymorphism.

Java has introduced object-oriented wrappers and ends up with different and incompatible implementations for one and the same thing with is even more strange.

A better possibility for providing fast abstractions for numbers would be the introduction of typeclasses/concepts like in Haskell or C++ where you could write:

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

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

Dario
Value types are value types because they are passed by value, *not* because they just happen to be allocated on the stack in C#. Eric Lippert had numerous blog entries on this very topic.
Joey
A: 

You could create an extension to Object that returns a bool for you, like so (untested, may provide false positives, etc.) (catches decimals, floats, ints, using US style delimiter for decimal; modify regex to fit hex, etc 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 object...

Granted, this won't provide type safety or generics or anything like that, but it will still let you do similar things with a little more work. You didn't specify what you wanted the base class for, whether you want accept any numeric type as an argument someplace, or you wanted generics. This may get you partway to wherever you were going though.

Usage:

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;
        }
    }
}
Chad Ruppert
You can check type too, this was 2 lines, instead of a huge case statement, and provided for the base concept of adding Object extension methods to do this.
Chad Ruppert
Also, I thought I had acknowledged it wont catch everything and the regex could be modified if that was the way you wanted to go.
Chad Ruppert
+3  A: 

I don't know if true, but one explanation I heard was weight - in particular for the small frameworks (Compact Framework, Silverlight, Micro Framework); I'm not convinced by this...

Far more convincing is that by itself knowing it is a number doesn't provide much; for example, integer division works very differently to floating point, and operators aren't always as simple as you'd like (think DateTime + TimeSpan => DateTime, DateTime - DateTime => TimeSpan).

If it helps, MiscUtil offers generic operator support, allowing things like:

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

All very cleanly and efficiently. Note, however, that there is no compile-time validation (since there are no suitable generic constraints). But it works.

Marc Gravell
+1  A: 
BlueMonkMN