从字典中获取键和值对

时间:2012-03-27 18:41:24

标签: c# dictionary ienumerable

我想在一个类中存储欧元硬币的直径,并使用该类中的方法来获得硬币的直径值(值)。

首先我不确定使用课程并在初始化时建立字典是一个好主意或不是,所以如果你知道一个更好的方法请现在就让我。

其次,我为这个类写了这样的代码:

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 个答案:

答案 0 :(得分:5)

其他人已经使用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这样的值执行相等操作。在你给出的情况下它会正常工作,但是一旦你开始使用任何类型的算术,你最终都会导致问题。

答案 1 :(得分:4)

FirstOrDefault(x => x.Key == diameter)从词典中选择一个项目KeyValuePair。该方法需要返回decimal

您必须返回值或所选对。像这样:

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

答案 2 :(得分:2)

首先,您对FirstOrDefault的来电正在返回KeyValuePair<double, decimal>。您需要返回Value属性:

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

其次,在这种情况下初始化列表很好,但是我会考虑将这些数据存储在配置文件中并在运行时读取它(以便将来的更新不需要重新编译)。

第三,直径真的独一无二吗?如果你重复一个键:

  1. 您的初始化列表会在调用Add时失败;你不能Add两次同一把钥匙到一个dictinoary
  2. 您将丢失字典中的先前值(如果您没有使用Add,而是使用索引器设置器)
  3. 如果是这种情况,请考虑使用Dictionary<double, List<decimal>>。如果您以这种方式对它们进行分组,请考虑包装每个组以使您的代码更具可读性。

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

    这样,你也可以提供更多有关硬币的元数据(在Coin类中)

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

    我的一些想法。

答案 3 :(得分:1)

这更像是对你的“这是一个好主意”查询的答案,而不是你的实际问题和解决方案问题:

就个人而言,我建议您创建一个名为Coin的Type,它具有double属性和decimal属性。这是一个温和的例子,但是将概念作为原始特征集合进行管理的趋势是一种称为“原始痴迷”的代码气味。

如果你制作了一个硬币类型,你可以保留一个列表或枚举或其他比字典更容易维护和使用的东西。