tags:

views:

1496

answers:

5

Say I want to have a method that takes any kind of number, is there a base class (or some other concept) that I can use?

As far as I know I have to make overloads for all the different numeric types (Int32, Int16, Byte, UInt32, Double, Float, Decimal, etc). This seems awfully tedious. Either that or use the type "object" and throw exceptions if they are not convertable or assignable to a double - which is pretty bad as it means no compile time checking.

UPDATE: OK thanks for the comments, you are right Scarecrow and Marc, in fact declaring it as Double actually works for all except Decimal.

So the answer I was looking for is Double - it acts like a base class here since most numeric types are assignable to it. (I guess Decimal is not assignable to Double, as it could get too big.)

public void TestFormatDollars() {
 int i = 5;
 string str = FormatDollars(i);   // this is OK
 byte b = 5;
 str = FormatDollars(b);     // this is OK
 decimal d = 5;
 str = FormatDollars(d);     // this does not compile - decimal is not assignable to double
}

public static string FormatDollars(double num) {
 return "$" + num;
}
+7  A: 

There isn't one (or at least, not one that just means "numbers"). You could use:

void Foo<T>(T value) where T : struct {...}

But that allows any struct - not just numbers. If you want to do arithmetic, generic operators may be of use. Other than that; overloads it the most viable option.

Marc Gravell
+2  A: 

The base class of the numeric types is ValueType.

Unfortunately that still won't help you: DateTime, bool, Enum and hundreds of other types also derive from ValueType. There's no NumericType base class in .NET.

LukeH
Value types aren't necessarily numbers though, are they?
Lucas Lindström
ValueType also includes strings and other non-numeric value types, however.
Noldorin
@Noldorin, You're right that ValueType includes hundreds of non-numeric types, however string isn't one of them. String is a reference type (it just behaves a little bit like a value type).
LukeH
Also i can't use ValueType as a parameter declaration and then call it with a number, it says it can't find the best match overload.
mike nelson
@mike, I'm not sure what you mean - I can declare a method "public void Foo(ValueType val)" and pass numbers to it, although I can't really do anything useful with them inside the method.
LukeH
@Luke: Yeah, not sure why I said string! String is an immutable reference type, although it indeed appears like a value type.
Noldorin
@Luke - yes you are right, sorry i got that wrong, thanks for pointing that out. I have now gathered that in fact Double and Decimal cover almost all cases, so i only need two overloads and not squillions as i had first thought.
mike nelson
+7  A: 

The short answer is: Numeric types are value types, hence they derive from System.ValueType. The full answer is: you should read this article from MSDN. Moreover I think that you should read C# language reference :). Value type not equals numeric type, because values types include also structures and enumerations.

Dmitry Lobanov
The article from MSDN does not really consider what is the best type to use when you want a parameter to catch all kinds of number and nothing else - which is what i was asking.
mike nelson
Yes, but the article shows that decimal type and other floating-point types are different kind of types.
Dmitry Lobanov
A: 

Are overloaded method signitures out of the question here? If you want a constrained group of methods to performe the same task you could voerload the public method and call a private method that takes any number via casting the input to a double.

Greg B
Formally, that would be a conversion not a cast.
Marc Gravell
Well its not impossible, just annoying! Since there are a lot of numeric types. This seems to be the best solution but I was wondering if there was a better way.
mike nelson
+2  A: 

The answer is: you don't need to provide overloads for ALL the numeric types, just for Double and Decimal. All others (except maybe some very unusually large ones) will be automatically converted to these.

Not a base class but in fact that was the red herring. The base class System.ValueType doesn't help much as it includes types that are not numerics. The language reference i was reading was what got me confused in the first place :)

(I was just looking for who to attribute the answer to and it was a combination of Scarecrow and Marc Gravell, but since they were comments i have put the answer here)

mike nelson
Oh great, i can't accept my own answer -- despite Joel Spolsky saying last week that answering your own questions can be very helpful, Jeff Atwood sprinkles this system with innane rules.
mike nelson
Yeah. being able to provide a unit of information (A Q and A pair) seems like a good way to store knowledge for "future" generations. It shouldn't matter if you're the person that asked the original question or not, as if you're not qualified to answer your own question at a later time (it seems to me like that would be the ultimate proof that you actually understand the answers that you have been given).
Lucas Lindström