我想在C#中生成一个列表.我错过了python的列表推导.是否有一种C#方式来动态创建集合,如列表推导或生成器表达式在python中做?
如果您使用的是C#3.0(VS2008),则LINQ to Objects可以执行非常类似的操作:
ListfooList = new List (); IEnumerable extract = from foo in fooList where foo.Bar > 10 select Foo.Name.ToUpper();
Matt提到了查询表达式.顺便说一下,这些可用于LINQ - 不仅仅是LINQ to Objects.(例如,应用于LINQ to SQL datacontext的相同查询将执行数据库上的过滤器和投影.)
C#3中的查询表达式只是编写普通C#代码的语法糖 - 尽管查询表达式通常最终会调用扩展方法.(他们没有,并且编译器并不关心,但他们通常会这样做.)对于C#查询表达式中不可用但是方法调用支持的集合,可以执行各种操作,因此值得了解这两种语法.例如,Matt的查询表达式为:
ListfooList = new List (); IEnumerable extract = from foo in fooList where foo.Bar > 10 select foo.Name.ToUpper();
被"预处理"成:
ListfooList = new List (); IEnumerable extract = fooList.Where(foo => foo.Bar > 10) .Select(foo => foo.Name.ToUpper());
如果您希望(比方说)基于原始集合中的值的索引进行过滤,则可以使用通过查询表达式不可用的Where的适当重载:
ListfooList = new List (); IEnumerable extract = fooList.Where((foo, index) => foo.Bar > 10 + index) .Select(foo => foo.Name.ToUpper());
或者您可以找到符合条件的最长名称的长度:
ListfooList = new List (); int longestName = fooList.Where((foo, index) => foo.Bar > 10 + index) .Select(foo => foo.Name) .Max();
(你不必须做的不同的方法投影和最大-有一个Max
过载,这需要投影为好.)
我的观点是,使用扩展方法可以非常轻松地构建复杂的查询.
你也提到了Python生成器--C#以迭代器块的形式提供它.实际上,这些在实现类似LINQ的运算符时非常有用.(因为LINQ to Objects的大多数都是基于扩展方法的,所以你可以添加自己看起来像LINQ"本机"的运算符 - 虽然你不能自己改变查询表达式语法.)
List
通过对现有列表上的每个项执行相同的操作然后返回新集合,行为就像列表推导一样.如果您仍在使用.NET 2.0,这是使用Linq的替代方法.
在Python中,一个简单的列表理解示例:
>>> 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{ 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() { Listfoo = new List (new int[]{ 1, 2, 3}); List bar = foo.ConvertAll(new Converter (delegate(int x){ return x * 2; })); // list comprehension foreach (int x in bar) { Console.WriteLine(x); // should print 2 4 6 } }
(注意:使用Arrays可以完成相同的操作 Array.ConvertAll