【发布时间】:2011-06-07 15:48:32
【问题描述】:
我编写了以下代码来设置各种类的属性。它有效,但我的新年解决方案之一是尽可能多地使用 LINQ,显然这段代码没有。有没有办法以“纯 LINQ”格式重写它,最好不使用 foreach 循环? (如果可以在单个 LINQ 语句中完成,那就更好了 - 子语句很好。)
我试着玩弄join,但这并没有让我到任何地方,因此我要求回答这个问题 - 最好没有解释,因为我更愿意“反编译”解决方案弄清楚它是如何工作的。 (正如你可能猜到的那样,我目前在阅读 LINQ 方面比编写它要好得多,但我打算改变这一点......)
public void PopulateBlueprints(IEnumerable<Blueprint> blueprints)
{
XElement items = GetItems();
// item id => name mappings
var itemsDictionary = (
from item in items
select new
{
Id = Convert.ToUInt32(item.Attribute("id").Value),
Name = item.Attribute("name").Value,
}).Distinct().ToDictionary(pair => pair.Id, pair => pair.Name);
foreach (var blueprint in blueprints)
{
foreach (var material in blueprint.Input.Keys)
{
if (itemsDictionary.ContainsKey(material.Id))
{
material.Name = itemsDictionary[material.Id];
}
else
{
Console.WriteLine("m: " + material.Id);
}
}
if (itemsDictionary.ContainsKey(blueprint.Output.Id))
{
blueprint.Output.Name = itemsDictionary[blueprint.Output.Id];
}
else
{
Console.WriteLine("b: " + blueprint.Output.Id);
}
}
}
必要类的定义如下;它们只是数据的容器,我已经删除了所有与我的问题无关的部分:
public class Material
{
public uint Id { get; set; }
public string Name { get; set; }
}
public class Product
{
public uint Id { get; set; }
public string Name { get; set; }
}
public class Blueprint
{
public IDictionary<Material, uint> Input { get; set; }
public Product Output { get; set; }
}
【问题讨论】:
-
我对 .Net 并不熟悉,但我广泛使用它的同事对一个名为 ReSharper(JetBrains 出品)的工具赞不绝口,它有助于将 foreach 循环重构为 Linq 语句,以及许多其他美妙的东西.通过查看 ReSharper 的建议,他们对 Linq 有了更深入和更好的理解。可能想试试看?
-
@kander JFYI,我刚试过 Resharper。它不建议将其转换为 LINQ。