Question

Est-il possible dans .NET pour créer un type dérivé de décimales qui serait utilisé comme monnaie, il arrondit les opérations arithmétiques au nombre désiré de points décimaux.

Dans le cas contraire, quelles sont les meilleures pratiques pour en .NET?

EDIT (motivation):

Le mot Let J'ai un prix:

125.00 Rep$

et je vends des pièces 0.25 de celui-ci, qui revient à 31.25

Maintenant, j'ai un rabais de 15%, et une réduction de calculer et de le présenter en valeur absolue, je vais avoir:

31.25 * .85 = 26.5625

Si je inverse:

31.25 * .15 = 4.6875

Si je laisse un certain contrôle 3e partie à tronquer et l'afficher, par exemple, je pourrais avoir:

26.56 +
 4.68 =
-----
31.24

Et chaque comptable mangera votre foyer si vous lui donnez quelque chose comme ça.

Ajoutez la taxe ici, et multiplie autre problème.

Ainsi, le stockage NO autant de décimales et arrondi le plus tard possible. Créer une classe qui va le faire financièrement correct et stocker le plus rapidement possible arrondi / tronqué.

Était-ce utile?

La solution

Vous ne pouvez certainement pas créer un type dérivé de decimal, comme il est un struct -. Et vous ne pouvez pas créer des sous-types de struct

peut créer votre propre struct Currency qui contenu une décimale, cependant. Vous voudriez surcharger tous les opérateurs arithmétiques pour effectuer essentiellement l'arithmétique sur les valeurs décimales contenues et rond de façon appropriée.

Par exemple:

public struct Currency
{
    private readonly decimal value;

    public Currency(decimal value)
    {
        this.value = decimal.Round(value, 2);
    }

    public override string ToString()
    {
        return value.ToString();
    }

    public static Currency operator+(Currency left, Currency right)
    {
        return new Currency(left.value + right.value);
    }

    public static Currency operator-(Currency left, Currency right)
    {
        return new Currency(left.value - right.value);
    }

    public static Currency operator/(Currency left, int right)
    {
        return new Currency(left.value / right);
    }
}

class Test
{
    static void Main()
    {
        Currency currency = new Currency(15);
        Console.WriteLine(currency / 10); // Prints 1.5
        Console.WriteLine(currency / 100); // Prints 0.15
        Console.WriteLine(currency / 1000); // Prints 0.2
    }
}

(De toute évidence, il y a beaucoup plus nécessaire ici -. En particulier vous voulez remplacer GetHashCode et Equals, mettre en œuvre IEquatable<T> etc)

Est-ce vraiment ce que vous voulez bien? Je pensais qu'il était plus fréquent de garder autant de précision que vous pourriez pendant les opérations intermédiaires, et seulement ronde au dernier moment, par exemple pour le stockage dans une base de données ou un affichage à un utilisateur.

Autres conseils

Ce que vous proposez ne peut pas être fait directement (dérivant d'un type de valeur comme decimal). Il est également pas une bonne idée, puisque l'arrondissement après chaque opération arithmétique introduira des erreurs plus grandes et plus importantes dans le résultat final.

Si je comprends bien, ce que vous voulez atteindre est le mieux fait en utilisant decimal normalement, et en utilisant System.Math.Round une fois, à la fin pour arrondir.

System.Decimal devrait déjà avoir ce dont vous avez besoin, si vous utilisez le: La monnaie ( "C") Format Specifier pour produire une valeur décimale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top