Disons que je veux avoir une méthode qui prend n'importe quel nombre, y a-t-il une classe de base (ou un autre concept) que je peux utiliser?
Autant que je sache, je dois créer des surcharges pour tous les types numériques différents (Int32, Int16, Byte, UInt32, Double, Float, Decimal, etc.). Cela semble terriblement fastidieux. Soit ça, soit utilisez le type "objet" et lâchez des exceptions si elles ne sont pas convertibles ou assignables à un double - ce qui est assez grave car cela signifie qu'il n'y a pas de vérification de la compilation.
UPDATE: .__ OK, merci pour les commentaires, vous avez raison Scarecrow et Marc, le déclarer comme Double fonctionne en fait pour tous sauf Decimal.
La réponse que je cherchais est donc Double. Elle agit ici comme une classe de base car la plupart des types numériques lui sont assignables. (Je suppose que Decimal n'est pas assignable à Double, car il pourrait devenir trop gros.)
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;
}
La réponse est: vous n’avez pas besoin de fournir des surcharges pour TOUS les types numériques, mais seulement pour Double et Décimal . Toutes les autres (à l'exception peut-être de très grandes tailles) seront automatiquement converties en celles-ci.
Pas une classe base mais en fait c'était le hareng rouge. La classe de base System.ValueType n'aide pas beaucoup car elle inclut des types qui ne sont pas numériques. La référence linguistique que je lisais est ce qui m'a le plus troublé :)
(Je cherchais simplement à qui attribuer la réponse et c'était une combinaison de Scarecrow et de Marc Gravell, mais comme il s'agissait de commentaires, j'ai mis la réponse ici)
Il n'y en a pas un (ou du moins, pas un qui juste signifie "nombres"). Vous pouvez utiliser:
void Foo<T>(T value) where T : struct {...}
Mais cela permet toute structure - pas seulement des nombres. Si vous voulez faire de l'arithmétique, les opérateurs génériques peuvent être utiles. Autre que ça; la surcharge l'option la plus viable.
La réponse courte est: Les types numériques sont des types de valeur, ils dérivent donc de System.ValueType. La réponse complète est: vous devriez lire cet article de MSDN . De plus, je pense que vous devriez lire la référence du langage C # :). Le type de valeur n'est pas égal au type numérique, car les types de valeur incluent également les structures et les énumérations.
Ce que je fais:
public interface INumeric<T>
{
T Zero { get; }
T One { get; }
T MaxValue { get; }
T MinValue { get; }
T Add(T a, T b);
// T Substract(....
// T Mult...
}
public struct Numeric:
INumeric<int>,
INumeric<float>,
INumeric<byte>,
INumeric<decimal>,
// INumeric<other types>
{
int INumeric<int>.Zero => 0;
int INumeric<int>.One => 1;
int INumeric<int>.MinValue => int.MinValue;
int INumeric<int>.MaxValue => int.MaxValue;
int INumeric<int>.Add(int x, int y) => x + y;
// other implementations...
}
Maintenant, vous pouvez l'utiliser dans une méthode:
bool IsZero<TNum, T>(TNum ops, T number)
where TNum : INumeric<T>
{
return number == ops.Zero;
}
ou méthode d'extension
public static bool IsZero<TNum, T>(this TNum ops, T number)
where TNum : INumeric<T>
{
return number == ops.Zero;
}
et dans votre code:
...
var n = new Numeric(); // can be an static prop
Console.WriteLine(IsZero(n, 5)); // false
Console.WriteLine(IsZero(n, 0f)); // true
Console.WriteLine(IsZero(n, "0")); // compiler error
ou, avec méthode d'extension:
Console.WriteLine(n.IsZero(5)); // false
Console.WriteLine(n.IsZero(0f)); // true
Console.WriteLine(n.IsZero("0")); // compiler error
La classe de base des types numériques est ValueType
.
Malheureusement, cela ne vous aidera toujours pas: DateTime
, bool
, Enum
et des centaines d'autres types dérivent également de ValueType
. Il n'y a pas de classe de base NumericType
dans .NET.
Les signatures de méthodes surchargées sont-elles hors de question ici?