Ciao大家, 我终于能够从.NET Framework 2.0切换到.NET Framework 4.0。
我正在尝试获得有关lambda表达式和LINQ的一些经验。
是否可以翻译:
for (int cont = 0;cont < args.Length; cont++)
Console.WriteLine("#" + cont + " " + "<" + args + ">");
进入单行lambda表达式,或者使用LINQ,甚至其他一些costruct我都不知道? 提前谢谢。
答案 0 :(得分:6)
LINQ操作不应该有副作用或执行操作。它们只应用于IEnumerable<T>
另一个IEnumerable<T>
(或IQueryable<T>
另一个IQueryable<T>
或IEnumerable<T>
)(或者如果聚合,请{ {1}},.Max
...单个结果)
请阅读http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx。
(请注意,这个问题在SO上提出了很多问题...例如我在这里回复ToList().ForEach in Linq,并看到类似问题的解决方案)
现在,如果你讨厌自己,你可以这样做:
.All
我们正在使用strs.Select((p, index) =>
{
Console.WriteLine("#" + index + " " + "<" + p + ">");
return true;
}).All(p => p);
来“实现”.All(p => p)
操作。这是因为Select
是“懒惰的”,如果没有人循环它将不会被执行。
从技术上讲,你甚至可以尝试对它进行一些模糊处理:
Select
(strs.Select((p, index) =>
{
Console.WriteLine("#" + index + " " + "<" + p + ">");
return false;
}).Any(p => p);
检查所有元素是否为All
,如果其中一个元素为true
则停止,因此必须循环所有元素(因为我们始终false
)。return true;
(如书面所示)检查至少有一个元素是Any
然后停止(但我们所有的元素都是true
,因为我们false
所以return false;
将循环所有元素)
现在......这些技术优于使用Any
的优势在于我们不会将ToList
“复制”到Array
只是为了使用“错误”方法List<T>
。如果List<T>
的{{1}}方法“错误”,将ForEach
复制到List<T>
只是为了使用它是双重错误的。
答案 1 :(得分:4)
你必须先了解一些事情。 LINQ是一个功能样式的API。它的主要目的是提供一种简单而简洁的方法来操作序列。
您的代码可以使用LINQ编写,但这是不可取的:将内容写入流(例如控制台)最好以命令式方式完成,并且您的请求有点金锤。 / p>
答案 2 :(得分:3)
我不知道你为什么要这样,但是:
args.ToList().ForEach(i => Console.WriteLine("#{0} <{1}>",
args.ToList().IndexOf(i),
i));
我想你确实要输出项目本身,而不是每行输出整个列表。
我已经使输出结构更好了。
IMO:您的原始代码更快更容易阅读。
答案 3 :(得分:1)
将它转换为lambda表达式是微不足道的,没用。
Action doLoop = ()=>{for (int cont = 0;cont < args.Length; cont++)
Console.WriteLine("#" + cont + " " + "<" + args + ">");}
但是如果你想用linq替换循环,这可能是一个坏主意。 Linq专为无副作用代码而设计,Console.WriteLine
是副作用。
如果您想使用linq,但仍然可以保留Console.WriteLine
来电:
foreach(string s in Enumerable.Range(0,args.Length).Select("#" + cont + " " + "<" + args + ">"))
Console.WriteLine(s);
有可能滥用Select
来完全消除循环,但这太难看了,不能在这里发布。
许多人定义了一个ForEach
扩展方法,代码变为:
Enumerable.Range(0,args.Count).ForEach(()=>Console.WriteLine("#" + cont + " " + "<" + args + ">"));
但我不喜欢这种风格。
答案 4 :(得分:1)
答案 5 :(得分:1)
这将完全符合您的要求:
args
.Select((x, n) => String.Format("#{0} <{1}>", n, args))
.ToList()
.ForEach(Console.WriteLine);
它产生的代码与您的代码相同:
#0 <System.String[]>
#1 <System.String[]>
#2 <System.String[]>
我猜你想要更像这样的东西:
var args = new [] { "Apple", "Banana", "Cherry", };
args
.Select((x, n) => String.Format("#{0} <{1}>", n, x))
.ToList()
.ForEach(Console.WriteLine);
产生:
#0 <Apple>
#1 <Banana>
#2 <Cherry>
答案 6 :(得分:0)
假设这样的事情:
string[] args = new string[] { "a", "pippo", "c" };
你可以试试这个:
args.ToList().ForEach(
p => Console.WriteLine(
String.Format("# {0} <{1}>", p, args.Length)));
答案 7 :(得分:-1)
你的args必须是一个数组:
Array.ForEach(args, s => { Console.WriteLine("#" + Array.IndexOf(args, s) + " " + "<" + args + ">"); });