【问题标题】:Not All Paths Return a Value. Does Switch behave differently from Select?并非所有路径都返回值。 Switch 的行为是否与 Select 不同?
【发布时间】:2017-01-18 01:49:22
【问题描述】:

美好的一天。我正在从 vb.net 过渡到 C#,而我日历中的这个特定 switch 语句在 vb.net 上运行,但在 C# 上不运行。

这是我在 VB.Net 中的代码:

Function getlabel(ByVal day As DayOfWeek, ByVal row As Integer) As System.Windows.Forms.Label
    Select Case day
        Case DayOfWeek.Sunday
            Select Case row
                Case 1
                    Return su1
                Case 2
                    Return su2
                Case 3
                    Return su3
                Case 4
                    Return su4
                Case 5
                    Return su5
                Case 6
                    Return su6
            End Select

        Case DayOfWeek.Monday
            Select Case row
                Case 1
                    Return m1
                Case 2
                    Return m2
                Case 3
                    Return m3
                Case 4
                    Return m4
                Case 5
                    Return m5
                Case 6
                    Return m6
            End Select

        Case DayOfWeek.Tuesday
            Select Case row
                Case 1
                    Return tu1
                Case 2
                    Return tu2
                Case 3
                    Return tu3
                Case 4
                    Return tu4
                Case 5
                    Return tu5
                Case 6
                    Return tu6
            End Select

        Case DayOfWeek.Wednesday
            Select Case row
                Case 1
                    Return w1
                Case 2
                    Return w2
                Case 3
                    Return w3
                Case 4
                    Return w4
                Case 5
                    Return w5
                Case 6
                    Return w6
            End Select

        Case DayOfWeek.Thursday
            Select Case row
                Case 1
                    Return th1
                Case 2
                    Return th2
                Case 3
                    Return th3
                Case 4
                    Return th4
                Case 5
                    Return th5
                Case 6
                    Return th6
            End Select

        Case DayOfWeek.Friday
            Select Case row
                Case 1
                    Return f1
                Case 2
                    Return f2
                Case 3
                    Return f3
                Case 4
                    Return f4
                Case 5
                    Return f5
                Case 6
                    Return f6
            End Select

        Case DayOfWeek.Saturday
            Select Case row
                Case 1
                    Return sa1
                Case 2
                    Return sa2
                Case 3
                    Return sa3
                Case 4
                    Return sa4
                Case 5
                    Return sa5
                Case 6
                    Return sa6
            End Select

    End Select
End Function

这是我尝试在 C# 中重新创建的代码:

        public System.Windows.Forms.Label getlabel(DayOfWeek day, int row)
    {
        switch (day)
        {
            case DayOfWeek.Sunday:
                switch (row)
                {
                    case 1:
                        return su1;
                    case 2:
                        return su2;
                    case 3:
                        return su3;
                    case 4:
                        return su4;
                    case 5:
                        return su5;
                    case 6:
                        return su6;
                }

                break;
            case DayOfWeek.Monday:
                switch (row)
                {
                    case 1:
                        return m1;
                    case 2:
                        return m2;
                    case 3:
                        return m3;
                    case 4:
                        return m4;
                    case 5:
                        return m5;
                    case 6:
                        return m6;
                }

                break;
            case DayOfWeek.Tuesday:
                switch (row)
                {
                    case 1:
                        return tu1;
                    case 2:
                        return tu2;
                    case 3:
                        return tu3;
                    case 4:
                        return tu4;
                    case 5:
                        return tu5;
                    case 6:
                        return tu6;
                }

                break;
            case DayOfWeek.Wednesday:
                switch (row)
                {
                    case 1:
                        return w1;
                    case 2:
                        return w2;
                    case 3:
                        return w3;
                    case 4:
                        return w4;
                    case 5:
                        return w5;
                    case 6:
                        return w6;
                }

                break;
            case DayOfWeek.Thursday:
                switch (row)
                {
                    case 1:
                        return th1;
                    case 2:
                        return th2;
                    case 3:
                        return th3;
                    case 4:
                        return th4;
                    case 5:
                        return th5;
                    case 6:
                        return th6;
                }

                break;
            case DayOfWeek.Friday:
                switch (row)
                {
                    case 1:
                        return f1;
                    case 2:
                        return f2;
                    case 3:
                        return f3;
                    case 4:
                        return f4;
                    case 5:
                        return f5;
                    case 6:
                        return f6;
                }

                break;
            case DayOfWeek.Saturday:
                switch (row)
                {
                    case 1:
                        return sa1;
                    case 2:
                        return sa2;
                    case 3:
                        return sa3;
                    case 4:
                        return sa4;
                    case 5:
                        return sa5;
                    case 6:
                        return sa6;
                }

                break;
        }
    }

我无法判断 Switch 的行为是否与我将“As System.Windows.Forms.Label”翻译错误?希望有人能赐教。

【问题讨论】:

  • 您在 VB 中应该有相同的 Not All Paths... 错误 - 它无法知道您的 Case 语句是详尽无遗的。不同的是,在 VB 中它只是一个警告
  • 说到筋疲力尽 - 可以通过消除 Select case 行并使用数组来折叠:Case DayOfWeek.Monday ... Return MondayLabels(row)
  • 答案是肯定的,它们是不同的。因为,它们是两种完全不同的语言。生成的程序集兼容但语法不兼容。
  • 您应该在 VB 中设置 Option Strict On - 您可能会在您的 VB 代码中遇到大量错误。这将帮助您正确更改为 C#。
  • @Plutonix,谢谢你的提示。我的编码技能真的不是那么好。我会把它折叠起来。

标签: c# vb.net


【解决方案1】:

当你从 switch 语句返回一个值时,你还需要关心 switch 的默认大小写,因为每个 case 都是方法中的代码路径,否则你必须在外面使用return null;你所有的switches。

你需要添加到你所有的 switch 语句中

 default: return null;
 break;

或return null在所有情况之外并且在离开块之前,因此如果找到任何匹配的情况,它将从该方法返回否则将返回null,代码将如下所示:

public System.Windows.Forms.Label getlabel(DayOfWeek day, int row)
{
   switch (day)
   {
     // cases here 
       switch (row)
       {
         // inner switch with its own cases
        // no specified default case
       }
     // no specified default case
   }
  return null;
}

在 VB 的情况下,如果你使用 Option Strict On 运行肯定会遇到同样的错误,在这种情况下你必须使用 case else 或简单地使用 return null 才能结束功能块

【讨论】:

  • 虽然是真的,但它没有回答为什么 VB 代码不需要这样的结构
  • 更清楚的是,只在末尾添加一个return null - 而不是任何switch。
  • @BradleyDotNET 是的。这真的让我很困扰。我真的开始后悔沉迷于VB了。过渡确实令人困惑。
  • @SlicedBread 对过渡点的评论:反向(从 C# 到 VB.Net)实际上并没有那么糟糕。 ;)
  • 刚刚检查过,所有不返回的代码路径只会在 VB 中引起警告,除非 Option Strict 开启。您的旧代码是否收到警告?
【解决方案2】:

这种设计修复了错误,即使没有任何情况找到匹配,函数也会返回一个值,如果没有匹配发生,这里就什么都没有了。

Function getlabel(ByVal day As DayOfWeek, ByVal row As Integer) As Label
  Dim result As Label = Nothing
  Select Case day
    Case DayOfWeek.Sunday
      Select Case row
      Case 1
        result = su1
      Case 2
        result = su2
      Case 3
        result = su3
      Case 4
        result = su4
      Case 5
        result = su5
      Case 6
        result = su6
    End Select
  'continue your cases.
  End Select
  Return result
End Function

【讨论】:

    【解决方案3】:

    VB.NET 中的这个程序可以运行:

    Module Module1
    
        Sub Main()
            Dim result = MyFunc(3)
            Console.WriteLine(result)
        End Sub
    
        Function MyFunc(ByVal variableName As Int16) As MyEnum
    
            Select Case variableName
                Case 1
                    Return MyEnum.ValueOne
                Case 2
                    Return MyEnum.ValueTwo
                'Case Else
                    'Throw New ArgumentException("Invalid value")
            End Select
        End Function
    
    End Module
    
    Enum MyEnum
        ValueOne
        ValueTwo
    End Enum
    

    MyFunc 将返回 0 作为默认值。在 C# 中,同一个程序会抱怨并非所有路径都返回值并且编译会失败。

    对于 VB.NET,它只会显示警告并且编译将通过。如果你打开Option Explicit,那么VB.NET也会编译失败。

    所以要回答你的问题,在 C# 中它不是可选的:你必须返回一个值。

    请阅读this关于C# switch 语句的文章——内容丰富且详细。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多