>>> foo = [1, 2, 3]
>>> bar = [x * 2 for x in foo]
>>> bar
[2, 4, 6]
对于C#3.0,可以传递一个lambda函数,指定需要什么类型的映射函数。
public static void Main()
{
var foo = new List<int>{ 1, 2, 3};
var bar = foo.ConvertAll(x => x * 2); // list comprehension
foreach (var x in bar)
{
Console.WriteLine(x); // should print 2 4 6
}
}
对于C#2.0,可以使用带有Converter委托的匿名方法来执行等效的操作。
public static void Main()
{
List<int> foo = new List<int>(new int[]{ 1, 2, 3});
List<int> bar = foo.ConvertAll(new Converter<int, int>(delegate(int x){ return x * 2; })); // list comprehension
foreach (int x in bar)
{
Console.WriteLine(x); // should print 2 4 6
}
}
如果您使用的是C#3.0(VS2008),那么LINQ to Objects可以执行非常类似的操作:
Matt提到了查询表达式。顺便说一句,这些通常可用于LINQ,而不仅仅是LINQ to对象。(例如,应用于linqtosqldatacontext的同一查询将在数据库上执行筛选和投影。)
C#3中的查询表达式只是编写普通C#代码时的语法糖,尽管查询表达式通常最终调用extension methods。(它们不必这样做,编译器也不在乎,但它们通常会这样做。)对于在C查询表达式中不可用但由方法调用支持的集合,可以做很多事情,因此值得注意这两种语法。例如,Matt的查询表达式:
“预处理”为:
如果要(比方说)基于原始集合中值的索引进行筛选,可以使用通过查询表达式不可用的appropriate overload of Where:
或者可以找到与条件匹配的最长名称的长度:
(您不需要在单独的方法中使用来执行projection和max——还有一个
Max
重载也需要一个projection。)我的观点是,使用扩展方法可以非常容易地构建复杂的查询。
您还提到了Python生成器-C以iterator blocks的形式提供了它。实际上,在实现类似LINQ的操作符时,这些方法非常有用。(因为大多数LINQ to对象都是基于扩展方法的,所以您可以添加自己的操作符,这些操作符看起来像LINQ的“原生”操作符——尽管您自己不能更改查询表达式语法。)
^{} 的行为就像列表理解一样,对现有列表中的每个项执行相同的操作,然后返回一个新集合。这是使用Linq的一种替代方法,特别是当您仍在使用.NET 2.0时。
在Python中,一个简单的列表理解示例:
对于C#3.0,可以传递一个lambda函数,指定需要什么类型的映射函数。
对于C#2.0,可以使用带有
Converter
委托的匿名方法来执行等效的操作。(注意:使用^{} 的数组也可以这样做)
相关问题 更多 >
编程相关推荐