Introduction
Money is a blood of Economy. So a large amount of applications handle monetary values - finance and trading applications, every app that allows users to sell or buy something, and even computer games. Probably, most of apps operates with money. But as developers we still don't have special data type for using within monetary value in base class libraries in programming languages that we use and the lack of such type causes some troubles.
In this short article I'm going to explain Money Pattern suggested by Martin Fowler in his book "Patterns of Enterprise Application Architecture" that solves that troubles. I'm going to cover a few things - what it is, why do we need it and where it is applicable. I want to get across my idea about using this pattern and suggest my implementation of .NET class library that implements the pattern.
Background
The lack of special data type for representing monetary value is not a big deal when your application manipulates only one currency. But if you are working on app that operates multiple currencies it definitely might become the source of headache and some unpleasant mistakes. I suppose you want to avoid the situation when your or your colleagues' code performs any calculation with different currencies without conversion according to exchange rate. And I have faced with this situation in my developer practice more than once. Projects grow, money data come from different sources - databases, XML, SOAP and different currencies, new developers join the team. And here we are - someone adding dollars to euro or comparing 100 dollars with 100 euro without taking into account exchange rate. Slightly worrying situation, isn't it? It is. And I'm totally agree with Martin Fowler who suppose that Money data type should be implemented in all mainstream programming languages by default.
The key idea of Money Pattern is using special reference data type for representing monetary value which contains:
- Amount of money
- Currency of monetary value
- Overloaded comparison operators that do not allow perform comparison without taking into account exchange rate
- Overloaded arithmetic operators that do not allow to perform calculations with different currencies without conversion one to another.
- Some other helper methods which might be usefull for working with money
Pic. Money Pattern by Martin Fowler

So I created class library which contains Money
class - my implementation of this pattern for .NET developers. You can use it "as-is" or modify the code on your own.
Using the Money class
At first, I'm going to show how to use my implementation of Money pattern. Then I'm going to talk about the implementation. In order to use Money
type you should add reference to Sybinfotech.Finance
library into your project.
Then, you can create instances of Money
class or use it's extension methods for common value types. I' going to demonstrate all the methods that it has and how it works in short pieces of code.
Аt first, let's create a couple of instances of the class in different currencies and try convert one to another using static method ConvertToCurrency(Money sourceValue, Currency destinationCurrency, double exchangeRate)
:
Money euroMoney = new Money(100.2, Currency.EUR);
Money dollars = Money.ConvertToCurrency(euroMoney, Currency.USD, 1.25);
Console.WriteLine("{0} euro = {1} dollars ", euroMoney.Amount, dollars.Amount);
Now, we are going to try what I was talking above - perform some calculations on different currencies:
var sum = euroMoney + dollars;
This code will throw InvalidCastException
as expected cause we are trying to add money in different currencies. You will get the same exception for all arithmetic operations in case of different currencies of operands.
Also you can get instance of Money
from value types using extension method ToMoney()
:
var sum = 150.ToMoney(Currency.USD) + Money.ConvertToCurrency(15.5.ToMoney(Currency.EUR), Currency.USD, 1.25);
Console.WriteLine(sum);
Now that's ok. We convert euro before adding to dollars. And there is one more property which finance apps often need for creating reports - Text
. It returns text representation of Money
instance taking into account money currency:
Console.WriteLine(125.15.ToMoney(Currency.USD).Text);
Console.WriteLine(125.15.MoneyToText(Currency.USD));
Console.WriteLine(1205.ToMoney(Currency.RUR).Text);
As you can see there is other one extension method for value types - MoneyToText
, which allows us to get text representation of money amount without explicit creation of Money
instance.
The Money class

My implementation of Money pattern -the Money
class, contains several public properties:
public decimal Amount { get; set; }
public Currency SelectedCurrency { get; set; }
public string Text
{
get
{
return AmountToText();
}
}
I should notice that every instance of Money
has public property of type Currency
which specify selected currency for concrete instance of Money
type. Currency
is just an enum and you can extend it with new currencies:
public enum Currency
{
RUR, USD, EUR
}
And you should specify Currency
when you create new instance of Money
. For arithmetic operations on Money
instances the class implemets overloaded aritmetic operators:
public static Money operator +(Money firstValue, Money secondValue);
public static Money operator -(Money firstValue, Money secondValue);
public static Money operator *(Money firstValue, Money secondValue);
public static Money operator /(Money firstValue, Money secondValue);
These operators do not allow to performs any calculations between different currencies without conversion according to exchange rate. If you want to calculate different currencies you must use static ConvertToCurrency
method for one of operands:
public static Money ConvertToCurrency(Money sourceValue, Currency destinationCurrency, double exchangeRate);
For performing correct comparison between currencies the Money
class overrides Equals
method:
public override bool Equals(object obj)
{
if (obj == null) return false;
Money money = obj as Money;
return (this.Amount == money.Amount && this.SelectedCurrency == money.SelectedCurrency);
}
public bool Equals(Money money)
{
if ((object)money == null) return false;
return (this.Amount == money.Amount && this.SelectedCurrency == money.SelectedCurrency);
}
And overloaded ==
operator returns true
only if both Money
instances have the same value for Amount
property and SelectedCurrency
. There are all comparison operators overloaded in the class.
In case if you want to implement text representation for new currency you should modify AmountToText() method and implement methods that return text representation by analogy:
private string AmountToText()
{
string sumText = "";
switch (this.SelectedCurrency)
{
case Currency.RUR:
if (this.IntegralPart != 0)
sumText += GetAmountTextRUR(this.IntegralPart) + " руб. ";
if (this.FractionalPart != 0)
sumText += GetAmountFractionalTextRUR(this.FractionalPart) + " коп.";
break;
case Currency.USD:
if (this.IntegralPart != 0)
sumText += GetAmountTextEN(this.IntegralPart) + " dollars ";
if (this.FractionalPart != 0)
{
sumText += GetAmountFractionalTextEN(this.FractionalPart);
sumText += " ";
sumText += this.FractionalPart == 1 ? "cent" : "cents";
}
break;
case Currency.EUR:
if (this.IntegralPart != 0)
sumText += GetAmountTextEN(this.IntegralPart) + " euro ";
if (this.FractionalPart != 0)
{
sumText += GetAmountFractionalTextEN(this.FractionalPart);
sumText += " ";
sumText += this.FractionalPart == 1 ? "cent" : "cents";
}
break;
default: throw new NotImplementedException("There is no text representation converter for this currency!");
}
return sumText.Trim();
}
Sybinfotech.Finance
library also has another class - MoneyExtenshions
which contains extension methods for getting Money
instances and text representations from .NET value data types - decimal
, int
, double
.
public static Money ToMoney(this decimal amount, Currency currency)
public static Money ToMoney(this double amount, Currency currency)
...
public static string MoneyToText(this double amount, Currency currency)
public static string MoneyToText(this decimal amount, Currency currency)
...
Full source code of library with comments is attached.
Summary
In this article I've tried to explain Money pattern and suggest my own implementation of this pattern for .NET developers.
I hope that you found this article useful and please feel free to use or modificate the attached library that implements Money pattern.
Thanks!
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.