Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Linq扩展:for循环不可中断或继续_C#_Linq - Fatal编程技术网

C#Linq扩展:for循环不可中断或继续

C#Linq扩展:for循环不可中断或继续,c#,linq,C#,Linq,我最近实现了这个Linq扩展,用于自动测试。我知道我可以使用来进行循环;然而,同样在iOS中工作,我喜欢你在使用方法代码时能像读英语句子一样阅读它们 /// <summary> /// Repeats an action x times /// </summary> /// <param name="times">The number of times an action should be repeated</param> /// <par

我最近实现了这个Linq扩展,用于自动测试。我知道我可以使用
来进行
循环;然而,同样在iOS中工作,我喜欢你在使用方法代码时能像读英语句子一样阅读它们

/// <summary>
/// Repeats an action x times
/// </summary>
/// <param name="times">The number of times an action should be repeated</param>
/// <param name="action">The action that should be repeated</param>
public static void DoIt(Int32 times, Action<Int32> action)
{
    for (var i = 0; i < times; i++)
        action(i);
}
可以清楚地理解为“使用当前索引i执行5次”。然而,现在我想在我的常规代码中也使用这个调用,我注意到我不能使用
break
继续
DoIt
-块内


是否有可能使用现有语言支持的技术来转义Linq表达式?

您可以稍微将
操作
修改为
谓词

缺点是块的最后一行必须始终包含
返回false。您可以将其视为询问“立即停止”的谓词

因此,总结一下:

return true;  -> break
return false; -> continue
给孩子起个名字 我承认,解决方案不是很清晰:首先,使用布尔型语言有点混乱。但是,您可以通过引入
枚举来解决此问题:

public enum LoopResult : byte {
    Break = 1,
    Continue = 0,
    End = 0
}
End
实际上是
Continue
的别名,但可以被视为更“自然”的表达方式,在这种情况下,可以使用
函数重写
DoIt

C#缺少预处理器/预编译器
但此外,将
返回
部分放在代码中也不是很好的阅读方法。由于C#没有(标准)预编译器,因此我认为没有办法自动重写代码,这样就可以使用
break
continue
表达式。另一方面,预编译器会带来额外的麻烦,许多程序可能会因为预编译器太神奇而被破坏。

您可以稍微将
操作
修改为
谓词

缺点是块的最后一行必须始终包含
返回false。您可以将其视为询问“立即停止”的谓词

因此,总结一下:

return true;  -> break
return false; -> continue
给孩子起个名字 我承认,解决方案不是很清晰:首先,使用布尔型语言有点混乱。但是,您可以通过引入
枚举来解决此问题:

public enum LoopResult : byte {
    Break = 1,
    Continue = 0,
    End = 0
}
End
实际上是
Continue
的别名,但可以被视为更“自然”的表达方式,在这种情况下,可以使用
函数重写
DoIt

C#缺少预处理器/预编译器
但此外,将
返回
部分放在代码中也不是很好的阅读方法。由于C#没有(标准)预编译器,因此我认为没有办法自动重写代码,这样就可以使用
break
continue
表达式。另一方面,预编译器会带来额外的麻烦,许多程序可能会因为预编译器的魔力太大而崩溃。

这是可行的。返回false以过早退出循环

public static void DoIt(Int32 times, Func<int, bool> action)
{
    for (var i = 0; i < times; i++)
    {
        if (!action(i))
        {
            break;
        }
    }
    Console.WriteLine("Done");
    Console.ReadLine();
}

static void Main(string[] args)
{
    DoIt(5, i =>
    {
        Console.WriteLine(i);
        return i != 3;              // returning false exits the loop
    });
}
publicstaticvoiddoit(Int32次,Func动作)
{
对于(变量i=0;i<次;i++)
{
如果(!行动(i))
{
打破
}
}
控制台。写入线(“完成”);
Console.ReadLine();
}
静态void Main(字符串[]参数)
{
DoIt(5,i=>
{
控制台写入线(i);
return i!=3;//返回false退出循环
});
}

这样就行了。返回false以过早退出循环

public static void DoIt(Int32 times, Func<int, bool> action)
{
    for (var i = 0; i < times; i++)
    {
        if (!action(i))
        {
            break;
        }
    }
    Console.WriteLine("Done");
    Console.ReadLine();
}

static void Main(string[] args)
{
    DoIt(5, i =>
    {
        Console.WriteLine(i);
        return i != 3;              // returning false exits the loop
    });
}
publicstaticvoiddoit(Int32次,Func动作)
{
对于(变量i=0;i<次;i++)
{
如果(!行动(i))
{
打破
}
}
控制台。写入线(“完成”);
Console.ReadLine();
}
静态void Main(字符串[]参数)
{
DoIt(5,i=>
{
控制台写入线(i);
return i!=3;//返回false退出循环
});
}

我倾向于通过以下方式修改
DoIt
方法,使其更强大:

public static void DoIt<T>(
    T initial, Func<T, bool> condition, Func<T, T> iterate, Action<T> action)
{
    var t = initial;
    while (condition(t))
    {
        action(t);
        t = iterate(t);
    }
}
甚至这个:

DoIt(
    new { counter = 0, sum = 0 },
    t => t.sum < 50,
    t => new { counter = t.counter + 1, sum = t.sum + t.counter },
    t =>
    {
        Console.WriteLine(t.counter);
        Console.WriteLine(t.sum);
    });
DoIt(
新的{counter=0,sum=0},
t=>t.sum<50,
t=>new{counter=t.counter+1,sum=t.sum+t.counter},
t=>
{
控制台写入线(t计数器);
控制台写入线(t.sum);
});

我倾向于通过以下方式修改
DoIt
方法,使其更强大:

public static void DoIt<T>(
    T initial, Func<T, bool> condition, Func<T, T> iterate, Action<T> action)
{
    var t = initial;
    while (condition(t))
    {
        action(t);
        t = iterate(t);
    }
}
甚至这个:

DoIt(
    new { counter = 0, sum = 0 },
    t => t.sum < 50,
    t => new { counter = t.counter + 1, sum = t.sum + t.counter },
    t =>
    {
        Console.WriteLine(t.counter);
        Console.WriteLine(t.sum);
    });
DoIt(
新的{counter=0,sum=0},
t=>t.sum<50,
t=>new{counter=t.counter+1,sum=t.sum+t.counter},
t=>
{
控制台写入线(t计数器);
控制台写入线(t.sum);
});

您可以使用
返回
继续
。除非抛出异常(讨厌的),否则你不能真正地
break
。我能想到的唯一解决方案是返回一个bool并根据它进行break。而且,
DoIt(5,I=>Console.WriteLine(I))
的(int i=0;iYes,我不想在这里抛出异常。Return可以工作,但我无法继续DoIt调用之后可能出现的代码。您可能最好还是习惯C语言的惯用代码。能够在语言及其样式之间切换是一项很好的技能。您可以使用
Return
继续除非你抛出一个异常(讨厌的)。我能想到的唯一解决办法就是返回一个bool并根据它进行中断。而且,
DoIt(5,I=>Console.WriteLine(I))
看起来不像
那样英语(int i=0;iYes,我不想在这里抛出异常。返回将起作用,但我无法继续DoIt调用之后可能出现的代码。您可能最好只是习惯C#惯用代码。能够在语言和它们的样式之间切换是一项很好的技能。感谢您为此所做的努力,但总的来说,这会带来很多问题更多c
DoIt(
    new { counter = 0, sum = 0 },
    t => t.sum < 50,
    t => new { counter = t.counter + 1, sum = t.sum + t.counter },
    t =>
    {
        Console.WriteLine(t.counter);
        Console.WriteLine(t.sum);
    });