这是我在SO上所遇到的最困难的问题之一。 :)虽然标题可能没有意义,但希望这个问题本身会有。
假设我有一个像Dictionary<string, List<double>>
这样的数据结构,并且我有函数,然后将List<double>
作为参数:
Dictionary<string, List<double>> candy_positions = new Dictionary<string, List<double>>();
candy_positions.Add( "Godiva", new List<double> { 1.0, 2.0, 4.0 });
EatCandy( candy_positions["Godiva"]);
...
但是现在我已经决定我不想这样做。我想将Dictionary
替换为List<CandyPositions>
,其中CandyPositions看起来像这样:
public class CandyPositions
{
public double Sees;
public double Godiva;
public double Lindt;
}
但是,我真的想独自离开EatCandy()。显然,现在的问题是我的数据不能直接传递给方法。相反,我必须做一些蹩脚的事情:
List<CandyPositions> candy_positions = new List<CandyPositions>();
...
var positions = from x in candy_positions select x.Godiva;
EatCandy( positions.ToList());
每个时间我想调用该方法。我希望能够以更简单的方式做到这一点,例如:
EatCandy( candy_positions.GetPositionsFor( "Godiva"));
其中参数“Godiva”与CandyPositions类中的属性名称匹配。
在写完这个问题之后,我意识到它实际上不是关于转置数据 - 可以通过编写扩展方法来处理它的一部分。我不知道该怎么做的部分是传入属性名称,以便扩展方法可以接受它并将其与类的属性相关联。我也不想传入一个字符串,主要是因为这将为各种运行时错误打开大门。我知道如何通过将“Godiva”传递给我的扩展方法来完成这项工作。我真正想要传递的内容类似于CandyPositions.Godiva。
这个问题可能有点令人困惑,总而言之,我会接受以下两种答案中的最佳答案:
我目前的扩展方法如下:
public static List<double> GetPositions( this List<CandyPositions> positions, string candy_name)
{
return (from x in positions select x.GetType().GetProperty(candy_name).GetValue(x, null)).Cast<double>().ToList();
}
答案 0 :(得分:1)
好吧,你可以使用:
public static List<double> GetPositions(this List<CandyPositions> positions,
Func<CandyPositions, double> projection)
{
return positions.Select(projection).ToList();
}
并将其命名为:
EatCandy(candyPositions.GetPositions(x => x.Godiva));
另一方面,如果您可以更改EatCandy
以接受IEnumerable<double>
,则不需要额外的方法 - 您可以使用:
EatCandy(candyPositions.Select(x => x.Godiva));
根本没有编写额外的方法。
编辑:如果您需要一次迭代两个序列,有两个选项:
Zip
扩展方法。否则,你基本上可以写自己的:
using (var iterator1 = sequence1.GetEnumerator())
using (var iterator2 = sequence2.GetEnumerator())
{
while (iterator1.MoveNext() && iterator2.MoveNext())
{
var value1 = iterator1.Current;
var value2 = iterator2.Current;
// Use the values here
}
}