字典将为null键

时间:2017-01-22 18:33:59

标签: c# .net linq dictionary

我想从列表中创建一个Dictionary,所以我会用这种方式:

Dictionary<long, List<MyType>> miDicIdMyType = myList.GroupBy(x => x.ForeignKey)
                                              .ToDictionary(x => x.Key, x => x.ToList());

问题是有时属性可能为null,所以我可以创建字典,因为字典不允许空值作为键。

但在这种特殊情况下,我必须检查此属性是否为null,如果为null,则抛出异常,因为这是一个错误。在这个特定的方法中,我希望列表中的所有项在此属性中都不为空。

所以我可以这样做:

Dictionary<long, List<MyType>> miDicIdMyType = myList.GroupBy(x => (long)x.ForeignKey)
                                        .ToDictionary(x => x.Key, x => x.ToList());

它是一个转换为long,但如果它为null,我将收到错误。所以基本上我想这样做:

Dictionary<long, MyType> myDic = new Dictionary<long, myType>();
foreach (Mytype iterator in miList)
{
    if (iterator.ForeignKey == null)
    {
        throw new ArgumentNullException("Some items in the collection has null value and it is not expected.");
    }

    if (myDic.ContainsKey(iterator.ForeignKey) == false)
    {
        myDic.Add(iterator.ForeignKey, new List<MyType>());
    }

    myDic[iterator.ForeignKey].Add(iterator);
}

我想知道这是一个好代码,还是我可以用更好的方式,LINQ或lambda表达式或任何其他方式。我的意思是,简化我的代码。

2 个答案:

答案 0 :(得分:3)

您正在寻找类似的东西吗?

Dictionary<long, List<MyType>> miDicIdMyType = myList.GroupBy(x =>
{
    if (x.ForeignKey == null)
        throw new Exception();
    return x.ForeignKey.Value;
})
.ToDictionary(x => x.Key, x => x.ToList());

答案 1 :(得分:2)

首先,您要创建查找。就这样做:

var lookup = data.ToLookup(x => x.ForeignKey);

如果您需要对密钥进行额外检查,则命名方法会对可重用性和可读性产生奇迹。

T IsNotNull<T>(T? obj, [CallerMemberName] string name = default(string)) where T : struct
{
    if (obj == null)
        throw new ArgumentNullException(name);
    return obj.Value;
}

var lookup = data.ToLookup(x => IsNotNull(x.ForeignKey));

但我会提醒你甚至不要使用它。您的linq查询不应该依赖/导致副作用,尤其是在延迟评估时。你应该不惜一切代价防止例外情况,而不是寻找提出它们的理由。在这种特殊情况下,代码中此处的异常将是不合适的。这是一个应该过滤掉的简单数据问题。

为什么你不首先过滤那些?

var lookup = data.Where(x => x.ForeignKey != null).ToLookup(x => x.ForeignKey.Value);