15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

174 ❘ ChaPTer 7 OperAtOrs And cAsts<br />

}<br />

public override string ToString()<br />

{<br />

return string.Format( “ ${0}.{1, - 2:00} ” , Dollars,Cents);<br />

}<br />

code snippet SimpleCurrency/Program.cs<br />

The use of unsigned data types for the Dollar <strong>and</strong> Cents fi elds ensures that a Currency instance can hold<br />

only positive values. It is restricted this way to illustrate some points about explicit casts later on. You might<br />

want to use a class like this to hold, for example, salary information for employees of a company (people ’ s<br />

salaries tend not to be negative!). To keep the class simple, the fi elds are public, but usually you would make<br />

them private <strong>and</strong> defi ne corresponding properties for the dollars <strong>and</strong> cents.<br />

Start by assuming that you want to be able to convert Currency instances to float values, where the<br />

integer part of the float represents the dollars. In other words, you would like to be able to write code<br />

like this:<br />

Currency balance = new Currency(10,50);<br />

float f = balance; // We want f to be set to 10.5<br />

To be able to do this, you need to defi ne a cast. Hence, you add the following to your Currency definition:<br />

public static implicit operator float (Currency value)<br />

{<br />

return value.Dollars + (value.Cents/100.0f);<br />

}<br />

The preceding cast is implicit. It is a sensible choice in this case because, as should be clear from the<br />

defi nition of Currency , any value that can be stored in the currency can also be stored in a float . There is<br />

no way that anything should ever go wrong in this cast.<br />

There is a slight cheat here — in fact, when converting a uint to a float, there can be<br />

a loss in precision, but Microsoft has deemed this error suffi ciently marginal to count<br />

the uint-to-float cast as implicit.<br />

However, if you have a float that you would like to be converted to a Currency , the conversion is not<br />

guaranteed to work. A float can store negative values, which Currency instances can ’ t, <strong>and</strong> a float<br />

can store numbers of a far higher magnitude than can be stored in the ( uint ) Dollar fi eld of Currency .<br />

Therefore, if a float contains an inappropriate value, converting it to a Currency could give unpredictable<br />

results. Because of this risk, the conversion from float to Currency should be defi ned as explicit. Here is<br />

the fi rst attempt, which will not give quite the correct results, but it is instructive to examine why:<br />

public static explicit operator Currency (float value)<br />

{<br />

uint dollars = (uint)value;<br />

ushort cents = (ushort)((value - dollars) * 100);<br />

return new Currency(dollars, cents);<br />

}<br />

The following code will now successfully compile:<br />

float amount = 45.63f;<br />

Currency amount2 = (Currency)amount;<br />

However, the following code, if you tried it, would generate a compilation error, because it attempts to use<br />

an explicit cast implicitly:<br />

float amount = 45.63f;<br />

Currency amount2 = amount; // wrong<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!