我需要用更紧凑的东西替换C#开关

时间:2012-03-06 06:09:15

标签: c#

我有以下代码:

switch (pk.Substring(2, 2))
{
    case "00":
        ViewBag.Type = _reference.Get("14", model.Type).Value;
        break;
    case "01":
        ViewBag.Type = _reference.Get("18", model.Type).Value;
        break;
}

它完成了这项工作,但对我来说并不是很干净。有什么方法可以让这个代码变小一点。我想将数字14或18作为一个变量,但我不确定如果我应该使用if-else或其他方式进行编码的最佳方法。

5 个答案:

答案 0 :(得分:4)

您可以使用静态字典作为地图而不是switch语句。

 static readonly Dictionary<string, string> map = new Dictionary<string, string> {
     { "00", "14" },
     { "01", "18" },
     // ... more ...
 };

 // ... in your method ...

 string str = pk.Substring(2, 2);
 string val;

 if (!map.TryGetValue(str, out val))
 {
     // Handle error, like in the "default:" case of the switch statement
 }
 else
 {
     ViewBag.Type = _reference.Get(val, model.Type).Value;
 }

但是,我只会这样做,如果真的有很多映射甚至可以从配置文件等外部源“读取”。

另请注意,如果“key”实际上是从0开始的连续整数序列,您可能可以使用数组,其中“key”只是其中的索引。

 static readonly string[] map = new string[] {
    "14", "18", ...
 };

 int index = Int32.Parse(pk.Substring(2, 2)); // Error handling elided.

 if (index < 0 || index > map.Length)
 {
     // Handle error, like in the "default:" case of the switch statement
 }
 else
 {
     ViewBag.Type = _reference.Get(map[index], model.Type).Value;
 }

否则请继续使用显式切换语句(可能会将更简洁的代码分配出来):

 string val;

 switch (pk.Substring(2, 2))
 {
    case "00":
      val = "14";
      break;
    case "01":
      val = "18";
      break;

    // ... more ...

    default:
      // Error handling for unknown switch-value.
      break;
 }

 ViewBag.Type = _reference.Get(val, model.Type).Value;

答案 1 :(得分:3)

似乎“00” - &gt;“14”和“01” - &gt;“18”之间存在某种关系。我相信这种关系源于业务逻辑。您应该包装逻辑并使控制器中的代码清晰。最后,控制器中的代码应如下所示:

public ActionResult MyAction()
{
    //some code

    ViewBag.Type = TypeProvider.GetType(pk, model.Type);

    //return something
}

class TypeProvider
{
    Dictionary<string, string> relations = ...
         //a dictionary stores "00"->"14" logics

    public static SomeType GetType(string pk, Type modelType)
    {
        return _reference.Get(relations[pk.SubString(2,2)], modelType).Value;
    }
}

答案 2 :(得分:2)

var data = pk.Substring(2, 2);
var choice = data == "00" ? "14" : (data=="01"?"18":"");
if (choice != string.Empty) ViewBag.Type = _reference.Get(choice, model.Type).Value;

答案 3 :(得分:0)

我对这种代码使用映射扩展:

ViewBag.Type = pk.Substring(2, 2)
.Map("00", x => GetViewBagValue("14"))
.Map("01", x => GetViewBagValue("18"))

在你的情况下这个方法:

private ViewBagValue GetViewBagValue(string value)
{
    return _reference.Get(value, model.Type).Value; 
}

答案 4 :(得分:0)

我用这个。您可以轻松地将其更改为通用或使用例如对象[]而不是。不是超级高效,但非常紧凑:

public static class Util {
    public static string Switch(string value, params string[] nameValues) {
        for (int x = 0; x < nameValues.Length; x += 2) {
            if (nameValues[x] == value) {
                return nameValues[x + 1];
            }
        }
        return string.Empty;
    }
}

然后就这样打电话:

var res = Util.Switch("test2", "test1", "res1", "test2", "res2");

祝你好运!