【问题标题】:for loop - "Unreachable code detected" - Testfor 循环 - “检测到无法访问的代码” - 测试
【发布时间】:2018-02-23 20:52:20
【问题描述】:

我有以下测试需要通过:

[TestMethod]
public void ShouldRepeatANumberOfTimes()
{
    Simon simon = new Simon();
    Assert.AreEqual("hello hello hello", simon.Repeat("hello", 3)); 
    //So if parameter 3 was to be exchanged with 7, it would write "hello" seven times in one sentence.
}

对于这个作业,我认为 for 循环将是一个自然的解决方案。所以我尝试了这个:

internal object Repeat(string v1, int v2)
{
    for (int i = 0; i < v2; i++)
    {
        return "hello ";
    }

    return v1;
}

我收到以下错误:

检测到无法访问的代码。

具体来说,i++ 中的i 下方有一个“错误行”。任何人都能够发现什么是错的?提前致谢。

【问题讨论】:

  • 在第一个return 语句之后函数返回...
  • 您误解了return 的工作原理。

标签: c# object for-loop methods tdd


【解决方案1】:

您将无法到达“return v1”行,因为您的 for 循环中有“return "hello"”行。因此,您的程序在 for 循环中退出。

【讨论】:

  • return v1 可访问。当v20 时,循环永远不会运行。
【解决方案2】:

在第一次迭代 (i=0) 之后,您的方法将返回 return "hello ";,因此永远不会执行 i++。此外,您将无法到达return v1 行,因为您已经返回了其他东西。看来你想返回(hello v2 times + v1),所以你的代码应该是这样的(注意yield return的用法):

internal IEnumerable<string> Repeat(string v1, int v2)
{
    for (int i = 0; i < v2; i++)
    {
        yield return "hello ";
    }

    yield return v1;
}

【讨论】:

    【解决方案3】:

    它应该可以工作

    internal object Repeat(string v1, int v2)
    {
        var str = "";
    
        for (int i = 0; i < v2; i++)
        {
            str += " " + v1;
        }
    
        return str.Trim();
    

    }

    【讨论】:

    • str 应该以空字符串开头,或者i 以 1 开头。
    • 老实说我并不完全理解函数应该做什么。它应该将“hello”v2 次添加到 v1 还是应该返回 v1 重复 v2 次?
    • 上面有一个测试显示了预期的输出。
    • 已更新。我的错。
    • @thesystem 你能解释一下它是如何不起作用的吗?它返回的是什么?您期望返回什么?
    【解决方案4】:

    由于您在第一次迭代期间总是返回一些东西,因此您只运行一次循环。因此 for 循环中的 i++ 永远不会执行。

    此外,正如 Devin Liu 正确指出的那样,从循环内部返回某些内容也会导致来自外部的 return v1 无法访问,因为您(再次总是)返回某些内容。

    【讨论】:

    • v20时,没有循环的第一次迭代。
    【解决方案5】:

    你有比那个错误更多的问题:

    在你的循环中,你总是返回“hello”,不管 v1。

    您在第一次迭代时返回 "hello ",因此它永远不会出现 return v1;

    如果您将 0 作为第二个参数传递,它仍然会返回一次 v1(从最后一次返回调用)。

    即使你修复了那个函数,如果你把它称为simon.Repeat("hello", 3),结果也会是"hellohellohello"

    您可以将函数重写为:

        String reps = String.Empty;
    
        for (int i = 0; i < v2; i++)
        {
            reps = string.Concat(reps, v1);
        }
    
        return reps;
    

    你的测试是:

        Assert.AreEqual("hellohellohello", simon.Repeat("hello", 3)); 
    

    【讨论】:

      【解决方案6】:

      如前所述,您的函数将始终以这一行结束

      return "hello ";
      

      要重复你的字符串,你可以使用这样的东西而不需要任何循环。

      return string.Join(" ", Enumerable.Repeat("Hello", 2));
      

      只需将这一行放在你的函数中,然后用你的参数替换 Hello2

      【讨论】:

        【解决方案7】:

        此方法将返回一个字符串而不是一个列表,并添加正确数量的空格,因为测试用例没有尾随空格。

        internal object Repeat(string v1, int v2)
        {
        
            var output = string.empty;
            for (int i = 0; i < v2; i++)
            {
                output += v1;
                if(i <= v2-1)
                {
                    output += " ";
                }
            }
        
            return output ;
        }
        

        我推荐的其他几种方法: 如果你认为你将构建非常大的字符串,我建议使用 StringBuilder,我不只是为了尽可能快地编写它。 您也可以删除循环末尾的尾随空格,我只是不想从头开始添加它。

        【讨论】:

          猜你喜欢
          • 2015-02-06
          • 2011-05-09
          • 1970-01-01
          • 2010-12-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-22
          相关资源
          最近更新 更多