Получение пар ключ-значение из словаря - PullRequest
2 голосов
/ 27 марта 2012

Я хочу хранить диаметр монет евро внутри класса и использовать метод в этом классе, чтобы получить ценность (ценность) монеты по ее диаметру.

Во-первых, я не уверен, что использование класса и построение его словаря на инициализации - хорошая идея или нет. Если вы знаете лучший способ, пожалуйста, дайте мне сейчас.

Во-вторых, я написал код для этого класса так:

class EuroCoinSpecs
{
    public Dictionary<double, decimal> CoinsDiameters;

    public EuroCoinSpecs()
    {
        CoinsDiameters = new Dictionary<double, decimal>
                        {
                            {25.75, 2.00m},
                            {23.25, 1.00m},
                            {24.25, 0.50m},
                            {22.25, 0.20m},
                            {19.75, 0.10m},
                            {21.25, 0.05m},
                            {18.75, 0.02m},
                            {16.25, 0.01m}
                        };
    }

    public decimal GetValueForDiameter(double diameter)
    {
        return CoinsDiameters.FirstOrDefault(x => x.Key == diameter);
    }
}

Проблема в том, что код в GetValueForDiameter не компилируется из-за этой ошибки:

Cannot implicitly convert type 'System.Collections.Generic.KeyValuePair<double,decimal>' to 'decimal'

Я пробовал разные способы, но он не хочет работать. В чем может быть проблема?

Ответы [ 4 ]

5 голосов
/ 27 марта 2012

Другие дали способ получения, используя FirstOrDefault - но мне это кажется довольно бессмысленным. Почему бы не использовать тот факт, что у вас есть словарь, который предназначен для поиска ключевых слов для вас?

public decimal GetValueForDiameter(double diameter)
{
    decimal ret;
    // This will set ret to 0m if the key isn't found.
    CoinsDiameters.TryGetValue(diameter, out ret);
    return ret;
}

Сказав все это, я бы настоятельно рекомендовал бы вам не выполнять операции равенства для double значений, подобных этой. В ваших случаях это будет хорошо работать, но как только вы начнете использовать какую-либо арифметику, у вас вполне могут возникнуть проблемы.

4 голосов
/ 27 марта 2012

FirstOrDefault(x => x.Key == diameter) выбирает элемент из словаря, который является KeyValuePair. И метод ожидает, что decimal будет возвращено!

Вы должны вернуть значение или выбранную пару. Как то так:

return CoinsDiameters.FirstOrDefault(x => x.Key == diameter).Value;
2 голосов
/ 27 марта 2012

Прежде всего, ваш звонок на FirstOrDefault возвращает KeyValuePair<double, decimal>. Вам нужно будет вернуть свойство Value:

return CoinsDiameters.FirstOrDefault(x => x.Key == diameter).Value;

Во-вторых, список инициализации в этом случае подходит, хотя я бы посоветовал сохранить эти данные в файле конфигурации и прочитать их во время выполнения (чтобы будущие обновления не нуждались в перекомпиляции).

В-третьих, действительно ли диаметр уникален? Если вы повторяете клавишу:

  1. Ваш список инициализации потерпит неудачу, поскольку он вызывает Add; Вы не можете Add один и тот же ключ дважды в диктовку
  2. Вы потеряете предыдущее значение в словаре (если вы используете не Add, а установщик индексатора)

Если это так, рассмотрите возможность использования Dictionary<double, List<decimal>>. Если вы группируете их таким образом, рассмотрите возможность обернуть каждую группу, чтобы сделать ваш код более читабельным.

class CoinGroup { public double Diameter {...} public ICollection<Coin> Coins { ... } }

Таким образом, вы также можете предоставить больше метаданных о монете (в классе Coin)

class Coin { public string Local {...} public decimal Value {...} }

Просто некоторые мысли, которые у меня были.

1 голос
/ 27 марта 2012

Это скорее ответ на ваш вопрос "это хорошая идея", чем ваш вопрос о кодах:

Лично я бы предложил создать тип с именем Coin, который имеет свойство double и свойство decimal. Это мягкий пример, но тенденция управлять концепциями как специальными коллекциями примитивов - это запах кода, называемый «Примитивная одержимость».

Если вы делаете тип монеты, вы можете сохранить список или перечисление или что-то еще, что проще, чем словарь для обслуживания и использования.

...