我想从列表中创建一个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表达式或任何其他方式。我的意思是,简化我的代码。
答案 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);