【问题标题】:Switch case with Boolean带布尔值的开关盒
【发布时间】:2013-05-15 18:50:26
【问题描述】:

我正在尝试为项目创建前缀文本值。我正在为此使用开关盒。当用户选择相关的单选按钮时,我们应该给出前缀值。

“switch()”之后应该给什么

来自用户选择的值是一个布尔值。 输出是字符串。

任何帮助..

 public string officePostfix()
  {
   string postfix = null;
     switch (...)
        {
            case SheetMgrForm.Goldcoast = true:
                postfix = "QLD";
                break;
            case SheetMgrForm.Melbourne = true:
                postfix = "MEL";
                break;
            case SheetMgrForm.Sydney = true:
                postfix = "SYD";
                break;
            case SheetMgrForm.Brisbane = true:
                postfix = "BIS";
                break;
        }
        return postfix;
     }

【问题讨论】:

  • 我认为你的设计不正确。您应该使用“区域”枚举或其他东西(数据库中的 ID 或标识条目的短代码),而不是每个区域的布尔字段。
  • 进一步这种事情看起来应该使用字典来完成......
  • 为什么不简单地使用 if 和 else 语句?

标签: c#


【解决方案1】:

您可以使用 C# 8 中的属性模式来做到这一点:

string officePostfix(SheetMgrForm test) => 
    test switch
    {
        { GoldCoast: true } => "QLD",
        { Melbourne: true } => "VIC",
        { Sydney: true } => "NSW",
        { Brisbane: true } => "BIS",
        _ => string.Empty
    };

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#property-patterns

【讨论】:

  • 注意,switch表达式不能作为语句使用~必须赋值或者返回see
【解决方案2】:

这可能会返回您想要的结果,但它是一种丑陋的蛮力方法。案例部分期望某种恒定值。在这种情况下,您将使用“case true:”或“case false:”(尽管在这种情况下我不确定您将如何处理)。

public string officePostfix()
{
    string postfix = null;
    switch (SheetMgrForm.Goldcoast == true)
    {
        case true:
            postfix = "QLD";
            break;
    }
    switch(SheetMgrForm.Melbourne == true)
    { 
        case true:
            postfix = "MEL";
            break;
    } 
    switch (SheetMgrForm.Sydney == true)
    {
        case true:
            postfix = "SYD";
            break;
    }     
    switch(SheetMgrForm.Brisbane == true)
    {
        case true:
            postfix = "BIS";
            break;
    }
        return postfix;
}

【讨论】:

  • 此时最好直接使用“IF”而不是switch
【解决方案3】:

另一种方法是使用枚举来定义您的区域,然后将它们映射到资源文件。这使它更易于维护,例如本地化或将来进一步扩展,如果列表很长,即通过 T4 自动创建枚举和资源,或者您必须查询 Web 服务或其他任何内容,可能会很有用......

例如,假设您有一个AreaPostfixes 资源文件和一个Area 枚举。

public enum Area
{
     Goldcoast,
     Melbourne,
     // ...
}

public static class AreaExtensions
{  
    public static string Postfix(this Area area)
    {
        return AreaPostfixes.ResourceManager.GetString(area.ToString());
    }
}

// AreaPostfixes.resx
Name       Value
Goldcoast  QLD
Melbourne  MEL

// Usage
public string GetPostfix(Area area)
{
    return area.Postfix();
}

这消除了对开关等的任何需求,您唯一需要确保的是每个枚举和资源都有 1:1 映射。我通过单元测试来做到这一点,但如果 GetString 在 Postfix 扩展方法中返回 null,则很容易放置断言或抛出异常。

【讨论】:

    【解决方案4】:

    switch 不是这样工作的。您不能在每个 case 中放置任意布尔表达式(假设您的意思是 == 而不是 =,顺便说一句)。

    您需要使用一组if-else 块,例如:

    if (SheetMgrForm.Goldcoast) {
        postfix = "QLD";
    } else if (SheetMgrForm.Melbourne) {
        postfix = "MEL";
    } else if ......
    

    不过,您的设计似乎需要进行一些返工。拥有所有这些单独的布尔值很笨拙。

    【讨论】:

    • 虽然这会起作用,但我无法表达我对看到有多少程序员坚持使用 if-else-if-else-if-else-... 构造而完美的可枚举类型将具有的不屑一顾完成或映射会更合适。
    【解决方案5】:

    switch 不支持这个。案例必须保持不变。案例也必须是唯一的。

    您需要将布尔属性转换为 enum 并关闭它,或者将您的开关更改为标准的 if 语句

    http://msdn.microsoft.com/en-us/library/06tc147t(v=vs.110).aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-21
      • 2012-02-09
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      • 2019-03-10
      • 2020-06-09
      • 2018-05-05
      相关资源
      最近更新 更多