2010-01-30 6 views
2

Je lisais un Business Primitives par CodeBetter.com et je jouais avec l'idée. En prenant son exemple de Money, comment l'implémenter de manière à ce qu'il puisse être utilisé de la même manière que les types de valeur standard?Surcharge de l'opérateur "Set to equal to"

Ce que je veux dire par là faire:

Money myMoney = 100.00m; 

Au lieu de:

Money myMoney = new Money(100.00m); 

Je comprends comment remplacer tous les opérateurs pour permettre la fonctionnalité faire des mathématiques etc, mais je n » Je ne sais pas ce qui doit être dépassé pour permettre ce que j'essaie de faire. L'idée est de minimiser les changements de code requis lors de la mise en œuvre du nouveau type, et de garder la même idée qu'il s'agit d'un type primitif, juste avec un nom de type valeur différent et une fonctionnalité de logique métier.

Idéalement, j'aurais hérité de Integer/Float/Decimal ou de tout ce qui est nécessaire, et redéfinir si nécessaire, mais évidemment ce n'est pas disponible pour les structures.

Répondre

7

Vous pouvez fournir un implicit cast operatordecimal-Money comme ceci:

class Money { 
    public decimal Amount { get; set; } 
    public Money(decimal amount) { 
     Amount = amount; 
    } 
    public static implicit operator Money(decimal amount) { 
     return new Money(amount); 
    } 
} 

Utilisation:

Money money = 100m; 
Console.WriteLine(money.Amount); 

Maintenant, ce se passe ici n'est pas que nous surchargeons l'opérateur d'affectation; ce n'est pas possible en C#. Au lieu de cela, ce que nous faisons fournit un opérateur qui peut implicitement transformer un decimal en Money si nécessaire. Ici, nous essayons d'affecter le littéral décimal 100m à une instance de type Money. Ensuite, dans les coulisses, le compilateur appelle l'opérateur de distribution implicite que nous avons défini et l'utilise pour affecter le résultat de la conversion à l'instance money de Money. Si vous voulez comprendre les mécanismes de ceci, lisez §7.16.1 et §6.1 de la spécification C# 3.0.

S'il vous plaît noter que les types que l'argent modèle doit être decimal sous le capot comme je l'ai montré ci-dessus.

+0

Aha, c'est ce que je cherchais! Est-il possible de le convertir implicitement en un type auquel il est assigné? Pourrais-je avoir par exemple: decimal dec = myMoney; –

+0

@Austitarum Custos: Oui, vous pourriez absolument.Il suffit de dire 'public implicite opérateur décimal décimal (Money money) {return money.Amount; } 'et ensuite' decimal d = money' est parfaitement légal. Donc les mots magiques que vous avez à incantation sont 'opérateur implicite statique public' et ensuite vous donnez le type de retour (donc ici' decimal') et ensuite, en tant que paramètre unique à l'opérateur, un paramètre du type que vous voulez convertir (donc ici 'Money'). Notez que le type de retour ou le type du paramètre doit être le type de la classe englobante. Ainsi 'chaîne d'opérateur implicite statique publique (int i)' n'est pas légale. – jason

+0

Bon à savoir ça marche dans les deux sens, merci! –

0

L'opérateur d'affectation ne peut pas être définie en C#, mais pour ce genre d'affectation vous pouvez surcharger l'opérateur de cast implicite:

(dans la classe d'argent)

public static implicit operator Money(double value) 
{ 
    return new Money(value); 
} 

Note: Je recommande d'utiliser décimal pour un calcul précis de l'argent

+1

S'il vous plaît ne jamais utiliser le double pour représenter l'argent! –

+0

@Dan voilà pourquoi il y a une note, l'utilisateur utilise un double littéral. –

+0

Désolé, quand je le tapais, cette note n'était pas là. –