It’s been a while, tot a release since last year! Let’s not be dramatic, it’s been one month-ish.
What’s up Doc?
- An strategy for deprecated currencies has been developed. More on this later.
- Estonian Kroon (EEK) has been deprecated using the above strategy.
- Currency.Get() and Currency.TryGet() have a new overload that receives a RegionInfo.
- HTML and XML entity support for those currencies that have an entity representation.
- Better NuGet support.
Let’s scratch the surface of this new release.
Currencies are volatile entities. They come and go, they get replaced by newer currencies and they remain in our memories… and our stored data. We can’t just get rid of them as if they never existed as we may have some data that used them when they were current tender. What I have done in NMoneys is let them retire and age gracefully.
Deprecated currency codes are marked as obsolete. I assumed that programmers are not supposed to create monetary quantities with deprecated currencies without knowing. They will notice a compiler warning and nice squiggles telling them about the use of a deprecated currency code. Fear not, currencies are not going anywhere, they are not going to be removed.
CurrencyIsoCode eek = CurrencyIsoCode.EEK; // squiggly EEK
Currency kroon = Currency.Get(CurrencyIsoCode.EEK); // squiggly too
Compiler warnings are ok, but what happens when a Currency is created from a string representing a deprecated currency? How about a CultureInfo that has not been updated yet? And how about a deserialized objects? Compilers are not going to help with these cases, as they happen in runtime. Since we want to allow the use of them, we should not throw an exception, but we still want to notify the user. Notification? Observer? Ring any bell? You guessed it right, a good old .NET event will be raised whenever a deprecated currency is created: factory methods, constructors and deserialization endpoints are covered.
But there is one catch. How can one raise an event from a constructor of a static factory method? There is no object instance to wire the callback to. The only remaining option is a static event. Not that static events are evil (they are, but they are sensitive creatures too, so we will not say it in loud voice) but they need to be handled with care. Why? Because they are one of the best ways to leak memory. I will only say it one million times, so pay attention:
“DO unsubscribe from static events when you do not want any more notifications” x 106
If one fails to do so, the object that contains the callback will not be garbage-collected as it is still referenced. And it always be as long as the callback gets unregistered from the list of delegates of the event. You have been warned.
public void Subscribing_To_Event()
Currency.ObsoleteCurrency += handler;
new Money(2, "EEK");
// please, do unsubscribe
Currency.ObsoleteCurrency -= handler;
public void handler(object sender, ObsoleteCurrencyEventArgs e)
// EEK should be written to the output
There is another catch. Statics have a very broad scope. Well, as broad as the whole running program. That means that you can register to the event before a very focused piece of code and still receive a notification from a totally unrelated usage in another area of the program than seems to be running at that very same moment. I have not yet figured out how to provide a way to narrow down the notification to a certain piece of code, but I am happy to be inspired. One workaround if to ask the Currency instance whether is obsolete or not.
public void Interrogating_The_Currency()
Currency kroon = Currency.Get("eek");
bool @veryTrue = kroon.IsObsolete;
Currency euro = Currency.Get("eur");
bool @letsHopeItRemainsFalseLongEnough = euro.IsObsolete;
Currencies tend to have exotic symbols. Some of them have symbols that have pretty standard characters and rendering them in HTML or XML shows no problem. Some others don’t and including them in HTML or XML will turn them to gibberish if you are lucky. A chosen few are sufficiently “important” to deserve their own html entity. For example the Euro has &eur;.
For those chose ones (and the rest of them) there is a Entity property that will return a CharacterReference object. this object contains the entity name information for those “chosen ones”. A snippet is worth a thousand words:
public void With_Entity()
CharacterReference reference = Currency.Pound.Entity;
reference.IsEmpty; // false
reference.EntityName; // £
reference.SimpleName; // pound
reference.EntityNumber; // £
reference.CodePoint; // 163
reference.Character; // £
For the not chosen ones there is also a CharacterReference object, but it is kind of empty:
public void Without_Entity()
CharacterReference reference = Currency.Zar.Entity;
reference.IsEmpty; // true
reference.EntityName; // "";
reference.SimpleName; // ""
reference.CodePoint; // 0
reference.Character; // ""
Get the bits
As before, one can et the latest binary release from the project page.
Now that NuGet has an approachable way of publishing packages, NMoneys is part of the official feed.
For those that prefer Gems, they are lucky too.
Daniel Gonzalez Garcia