在C#中处理switch case的更好方法

3

如果我的问题看起来非常愚蠢,请提前向您道歉,但出于某种原因,我无法找到更优雅的解决方法。因此,我有一个类似于以下代码块的利用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)
  • 不允许声明此方法

非常感谢您的建议..


2
你可以使用一个数组来存储String_1、String_2等项目(例如,称为stringsArray[]),然后可以像这样访问它们:stringsArray[item_1]。而不是Console.WriteLine($"{0} is displayed on the page", String_2);你可以使用Console.WriteLine($"{0} is displayed on the page", stringsArray[item_2]); - Phil N DeBlanc
2
或者考虑使用 Dictionary<Items, string> - Ben Cottrell
2
在进入switch块之前,调用这三个方法。在switch块内,按照你现在的方式调用控制台。这很简单。 - CodingYoshi
2个回答

7
您可以将enum ItemsString_X的映射存储在字典中,而不是依赖于switch语句。
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参数是否具有有效的映射,如果没有,则使用默认字符串。

我一定会尝试的。 - TiredOfProgramming

4
最简单的清理方法是引入一个变量。
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) - RubberDuck
我不明白为什么会有人踩我的回答。在被采纳的回答发布之前,我提供了至少和那个回答一样好的解决方案。这个网站有时候... - RubberDuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接