我有IntegerRectangle课。我希望它有一个internal_perimeter()方法,它返回其周长的所有点,而internal_perimeter(Action<Integer> processor)方法将processor应用到其周长的所有点。
我的一个类有一个变量IntegerRect canvas;和HashSet<IntegerPoint> forbidden_points,它调用:
canvas.internal_perimeter((IntegerPoint p)=>{forbidden_points.Add(p); print("[f]" + forbidden_points.Contains(p).ToString());});不同internal_perimeter()实现的结果不同
这样做是可行的:
public IEnumerable<IntegerPoint> internal_perimeter()
{
for(int i=0;i<width;++i)
{
yield return new IntegerPoint(x+i,y);
}
for(int i=1;i<height;++i)
{
yield return new IntegerPoint(x+width-1,y-i);
}
for(int i=width-2;i>=0;--i)
{
yield return new IntegerPoint(x+i,y-height+1);
}
for(int i=height-2;i>=0;--i)
{
yield return new IntegerPoint(x,y-i);
}
}
public void internal_perimeter(Action<IntegerPoint> processor)
{
foreach(IntegerPoint i in internal_perimeter())
processor(i);
}这并不是:
public IEnumerable<IntegerPoint> internal_perimeter(Action<IntegerPoint> processor=null)
{
if(processor==null)
{
for(int i=0;i<width;++i)
{
yield return new IntegerPoint(x+i,y);
}
for(int i=1;i<height;++i)
{
yield return new IntegerPoint(x+width-1,y-i);
}
for(int i=width-2;i>=0;--i)
{
yield return new IntegerPoint(x+i,y-height+1);
}
for(int i=height-2;i>=0;--i)
{
yield return new IntegerPoint(x,y-i);
}
}
else
foreach(IntegerPoint i in internal_perimeter())
processor(i);
}我不明白第二个怎么了
发布于 2014-08-19 11:47:46
第二个例子是迭代器(它使用yield return)。在枚举它之前,不会执行这种函数。
如果你这么做了:var x = internal_perimeter(i => {});
变量x将保存由编译器从函数构造的类的IEnumerable<IntegerPoint>。您的代码目前还没有执行。
现在,尝试使用它:foreach(var point in x) {}。这将执行您的功能。实际上,在特定情况下,所有这些都将在第一次迭代中执行,因此调用x.FirstOrDefault();就足够了。实际上,在枚举数上调用MoveNext将执行代码直到第一个yield return,并且代码的else分支中没有任何代码。
现在,我想举你的第一个例子,因为这一点。它不太容易出错。
发布于 2014-08-19 12:01:39
要添加到@Lucas' answer中,这可以回答为什么您的代码不能工作,您还应该考虑重构您的代码:
internal_perimeter是该方法的坏名称。如果它的目的是改变内部点,那么它应该被命名为void Process(Action a)或类似的东西。null时,它什么也不返回(空序列)。使用Func<T, Tresult (如LINQ )并返回所有处理过的参数将更有意义。而且,null分支非常少见(很少建议像这样传递null委托)。internal_perimeter重载也可能有一个更好的名称,例如,简单地说,GetPoints可以很好地说明它的目的是什么:
foreach (var point in rect.GetPoints()) DoStuff(point);https://stackoverflow.com/questions/25382524
复制相似问题