【问题标题】:Better way to handle switch case in C#在 C# 中处理 switch case 的更好方法
【发布时间】:2017-11-22 22:01:05
【问题描述】:

如果我的问题看起来很愚蠢,我会提前道歉,但由于某种原因,我无法通过更优雅的解决方案来解决问题。所以我有一个使用类似于以下代码块的 switch-case 块的方法:

public enum Items
{
    item_1, item_2, item_3, .... item_N
};

private string String_1 {get; set;}
private string String_2 {get; set;}
private string String_3 {get; set;}
// ...
private string String_N {get; set;}

public void DoSomething(Items item){
    switch(item){
        case item_1:
            MethodNumberOne();
            MethodNumberTwo();
            MethodNumberThree();
            Console.WriteLine($"{0} is displayed on the page", String_1);
            break;

        case item_2:
            MethodNumberOne();
            MethodNumberTwo();
            MethodNumberThree();
            Console.WriteLine($"{0} is displayed on the page", String_2);
            break;

        case item_3:
            MethodNumberOne();
            MethodNumberTwo();
            MethodNumberThree();
            Console.WriteLine($"{0} is displayed on the page", String_3);
            break;
        // ...
        case item_N:
            MethodNumberOne();
            MethodNumberTwo();
            MethodNumberThree();
            Console.WriteLine($"{0} is displayed on the page", String_N);

从上面的例子中可以看出switch语句调用的方法是一样的,唯一的区别就是最后一次Console调用。

我的问题:有没有更优雅的方法来处理这种情况,因为我不太喜欢重复代码。到目前为止,我尝试执行 Items 枚举以分离类并将其作为参数传递,但这种方法不起作用,因为静态类不能作为 C# 中的参数传递

public static class Items {
    public string String_1 {get; set;}
    public string String_2 {get; set;}
    public string String_3 {get; set;}
    // ...
    private string String_N {get; set;}
}

// ....

public void DoSomething(Items item)
  • 不允许声明此方法

任何建议都非常感谢..

【问题讨论】:

  • 你可以使用一个数组来保存你的 String_1、String_2 等项目(例如,称为 stringsArray[])然后你可以像这样访问它们 stringsArray[item_1] 而不是 Console.WriteLine($" {0} 显示在页面上", String_2);你会有 Console.WriteLine($"{0} is shown on the page", stringsArray[item_2]);
  • 或者,考虑Dictionary<Items, string>
  • 在进入 switch 块之前,调用这三个方法。在 switch 块中,按照您现在的方式调用控制台。这很简单。

标签: c# coding-style enums


【解决方案1】:

您可以将enum ItemsString_X 的映射存储在字典中,而不是依赖开关。

private IDictionary<Items, string> _itemStringMap = new Dicitionary<Items, string>()
{
   { Items.item_1, String_1 },
   //Other items here
};

public void DoSomething(Items item)
{
  var s = _itemStringMap[item];

  MethodNumberOne();
  MethodNumberTwo();
  MethodNumberThree();
  Console.WriteLine($"{0} is displayed on the page", s);
}

您可能需要检查item 参数是否具有有效映射,如果没有则使用默认字符串。

【讨论】:

  • 我一定会尝试的。
【解决方案2】:

最简单的清理方法是引入一个变量。

public void DoSomething(Items item){

    string foo;
    switch(item){
        case item_1:
            foo = String_1;
            break;

        case item_2:
            foo = String_2;
            break;

        case item_3:
            foo = String_3;
            break;
        // ...
        case item_N:
            foo = String_N;
            break;
    }

    MethodNumberOne();
    MethodNumberTwo();
    MethodNumberThree();
    Console.WriteLine($"{0} is displayed on the page", foo);

}

这清楚地表明我们真正拥有的是键/值对,因此我们可以更进一步并将字符串存储在字典中。

var dict = new Dictionary<Items,string>()
{
    { item_1, string_1 },
    { item_2, string_2 },
    //...
    { item_N, string_N }
}

MethodNumberOne();
MethodNumberTwo();
MethodNumberThree();
Console.WriteLine($"{0} is displayed on the page", dict[item]);

当然,您需要确保密钥(项目)有效、错误处理以及所有这些爵士乐。

【讨论】:

  • 哦。如果您使用字典,请务必先阅读它。我在回答中展示了一个使用索引器的示例,但是使用索引器有一些微妙之处。在实际代码中,您更有可能使用TryGetValue(item, out foo)
  • 我不明白反对意见。在发布之前,我提供了至少与接受的答案一样好的答案。这个网站有时..​​.
猜你喜欢
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多