简体   繁体   中英

C# Currency Converter: Reduce the amount of if statements

So far I have created a Currency Converter that will convert between multiple different currencies however, to convert the currency, I have used 4 if statements per currency (so I can convert between all of the different currencies.) This has resulted in 20 if statements which doesn't seem very clean or efficient. Here is an example of my code:

if (currencyFrom == "B" && currencyTo == "U")
{
    currencyConversion = doubleInput * 1.29;
    Console.WriteLine("$" + currencyConversion);
}
if (currencyFrom == "B" && currencyTo == "E")
{
    currencyConversion = doubleInput * 1.14;
    Console.WriteLine("€" + currencyConversion);
}
if (currencyFrom == "B" && currencyTo == "J")
{
    currencyConversion = doubleInput * 145.10;
    Console.WriteLine("¥‎" + currencyConversion);
}
if (currencyFrom == "B" && currencyTo == "C")
{
    currencyConversion = doubleInput * 1.68;
    Console.WriteLine("$‎" + currencyConversion);
}

Is there a better way to do the same calculations but without as many if statements?

Thanks for your help,

Josh

If you really want to reduce the amount of if-statements and your requirements do allow the use of internet-resources I have a very short code-sample that uses the Yahoo Finance

public decimal ConvertCurrency(string from, string to)
{
    var uriString = string.Format("http://finance.yahoo.com/d/quotes.csv?s={0}{1}=X&f=l1", from, to);
    string response = new WebClient().DownloadString(uriString);
    return decimal.Parse(response, System.Globalization.CultureInfo.InvariantCulture);
}

Or the async way:

public async Task<decimal> ConvertCurrencyAsync(string from, string to)
{
    var uriString = string.Format("http://finance.yahoo.com/d/quotes.csv?s={0}{1}=X&f=l1", from, to);
    string response = await new WebClient().DownloadStringTaskAsync(uriString);
    return decimal.Parse(response, System.Globalization.CultureInfo.InvariantCulture);
}

With that code you have the benefit to convert from and to any currency and you do have the current exchange rate.

You can use Dictionary

decimal currencyConversion;
        string currencyFrom = "B";
        string currencyTo = "E";
        decimal doubleInput = 1000m;

    Dictionary<string, decimal> dic = new Dictionary<string, decimal>();
    dic.Add("BU", 1.29m);
    dic.Add("BE", 1.14m);
    dic.Add("BJ", 145.10m);
    dic.Add("BC", 1.68m);

    currencyConversion = doubleInput * dic[currencyFrom + currencyTo];

Something like this should work.

if (currencyFrom == "B") {
    switch (currencyTo) {
        case "U":
            currencyConversion = doubleInput * 1.29;
            break;
        case "E":
            ...
    }
}

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch

As others have noted, using conditional logic like this does not make for a very scalable application. Switch is neater and simpler generally than using multiple if's, but there certainly would be more effective ways to re-design your application to make it scale better.

You could use a dictionary to store the conversion ratios and then have much more cleaner function to do the calculation.

First declare a ConcurrentDictionary (so you could even update the ratios on the fly thread safely).

private readonly static ConcurrentDictionary<Tuple<string, string>, double> ConversionRatios = new ConcurrentDictionary<Tuple<string, string>, double>();

You need to populate the ConversionRatios with your from and to currency pairs and their respective ratios.

static MyClass()
{
    ConversionRatios.TryAdd(new Tuple<string, string>("B", "U"), 1.29);
    ConversionRatios.TryAdd(new Tuple<string, string>("B", "E"), 1.14);
    ConversionRatios.TryAdd(new Tuple<string, string>("B", "J"), 145.10);
    ConversionRatios.TryAdd(new Tuple<string, string>("B", "C"), 1.68);
}

Then you can have a very simple convert function.

private static double Convert(double doubleInput, string currencyFrom, string currencyTo)
{
    double ratio;
    if (ConversionRatios.TryGetValue(new Tuple<string, string>(currencyFrom, currencyTo), out ratio))
    {
        return doubleInput * ratio;
    }

    // Handle case when no ratio is found, either throw exception or do what ever.
    throw new Exception("No ratio found.");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM