C# 如何推出我自己的锯齿Foreach?
我的应用程序经常迭代交错数组。我尝试实现类似foreach的功能,在这里我可以传递lambda,而不是到处都是显式的嵌套循环 我最近的尝试是:C# 如何推出我自己的锯齿Foreach?,c#,linq,lambda,C#,Linq,Lambda,我的应用程序经常迭代交错数组。我尝试实现类似foreach的功能,在这里我可以传递lambda,而不是到处都是显式的嵌套循环 我最近的尝试是: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace JaggedTest { static class Global {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JaggedTest
{
static class Global
{
// Does not work
public static void ForEachJagged<T>(Array A, System.Linq.Expressions.Expression<Action<T>> F)
{
foreach (var Item in A)
{
if (Item is Array)
{
ForEachJagged<T>((Array)Item, F);
}
else
{
System.Linq.Expressions.InvocationExpression Invo =
System.Linq.Expressions.Expression.Invoke(F,
System.Linq.Expressions.Expression.Constant(Item));
Console.WriteLine(Invo.ToString());
// How to execute "Invo" ?
}
}
}
}
class Program
{
static void Main(string[] args)
{
int[][] Foo = new int[3][] {
new int[] {1}
,new int[] {2,3,4,5,6}
,new int[] {7,8,9}
};
Global.ForEachJagged<int>(Foo, X => Console.Write(X.ToString() + " "));
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间JaggedTest
{
静态类全局
{
//不起作用
公共静态void ForEachJagged(数组A,System.Linq.Expressions.Expression F)
{
foreach(A中的var项目)
{
if(项为数组)
{
ForEachJagged((数组)项,F);
}
其他的
{
System.Linq.Expressions.InvocationExpression Invo=
System.Linq.Expressions.Expression.Invoke(F,
System.Linq.Expressions.Expression.Constant(Item));
Console.WriteLine(Invo.ToString());
//如何执行“发票”?
}
}
}
}
班级计划
{
静态void Main(字符串[]参数)
{
int[]Foo=新int[3][]{
新int[]{1}
,新int[]{2,3,4,5,6}
,新int[]{7,8,9}
};
Global.ForEachJagged(Foo,X=>Console.Write(X.ToString()+);
}
}
}
这个程序为lambda表达式生成预期的“ToString”调试输出,但我一直在尝试实际执行这个表达式。执行作为函数参数传递的lambda表达式的正确方法是什么
--编辑--
根据Slava Utesinov的反馈,工作锯齿状foreach:
public static void ForEachJagged<T>(Array A, Action<T> F)
{
foreach (var Item in A)
{
if (Item is Array)
{
ForEachJagged<T>((Array)Item, F);
}
else
{
F((T)Item);
}
}
}
publicstaticvoidforeachjagged(数组A,动作F)
{
foreach(A中的var项目)
{
if(项为数组)
{
ForEachJagged((数组)项,F);
}
其他的
{
F((T)项);
}
}
}
关于编译
方法:
foreach (var Item in A)
{
if (Item is Array)
ForEachJagged<T>((Array)Item, F);
else
F.Compile()((T)Item);
}
foreach(A中的变量项)
{
if(项为数组)
ForEachJagged((数组)项,F);
其他的
F.编译()((T)项);
}
关于编译
方法:
foreach (var Item in A)
{
if (Item is Array)
ForEachJagged<T>((Array)Item, F);
else
F.Compile()((T)Item);
}
foreach(A中的变量项)
{
if(项为数组)
ForEachJagged((数组)项,F);
其他的
F.编译()((T)项);
}
如果您真的因为每个循环只有一个foreach
循环而烦恼,您可以执行以下操作:
foreach (var item in arr.SelectMany(a => a))
{
Console.Write(item.ToString() + " ");
}
但实际上,我只是建议你做筑巢。为了让代码看起来更漂亮而付出的所有努力都是为了A)让代码看起来更漂亮,B)让代码运行得稍微慢一点,或者C)两者兼而有之
如果是缩进让你挂断,你可以让它看起来像这样:
foreach (var nest in arr)
foreach (var item in nest)
{
Console.Write(item.ToString() + " ");
}
如果您真的认为它只是一个
foreach
循环,您可以执行以下操作:
foreach (var item in arr.SelectMany(a => a))
{
Console.Write(item.ToString() + " ");
}
但实际上,我只是建议你做筑巢。为了让代码看起来更漂亮而付出的所有努力都是为了A)让代码看起来更漂亮,B)让代码运行得稍微慢一点,或者C)两者兼而有之
如果是缩进让你挂断,你可以让它看起来像这样:
foreach (var nest in arr)
foreach (var item in nest)
{
Console.Write(item.ToString() + " ");
}
谢谢斯拉瓦。这是可行的,但在我的实际应用程序中,JaggedForEach比嵌套循环慢得多。我想这种缓慢是由于Compile()造成的,但我不确定。只需使用
Action
而不是Expression
type,因此您需要调用F((T)项)
而不使用Compile
谢谢Slava。这是可行的,但在我的实际应用程序中,JaggedForEach比嵌套循环慢得多。我想这种缓慢是由于Compile()造成的,但我不确定。与其使用表达式
类型,不如使用操作
,因此您需要调用F((T)项)
而不使用编译
表达式的目的是什么。为什么不接受操作
?通常,只有当您希望将lambda“传输”到其他层时,才需要使用表达式树,就像您希望将C#中的LINQSelect
作为SQLSelect
在数据库中执行一样。@Martin,没有任何用途。我是C#新手,出轨了。表达式的目的是什么。为什么不接受操作
?通常,只有当您希望将lambda“传输”到其他层时,才需要使用表达式树,就像您希望将C#中的LINQSelect
作为SQLSelect
在数据库中执行一样。@Martin,没有任何用途。我是C#的新手,出轨了。