简体   繁体   English

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

[英]I need to replace a C# switch with something more compact

I have the following code: 我有以下代码:

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;
}

It does the job but does not look very clean to me. 它可以完成工作,但对我来说看起来并不干净。 Is there some way I could make this code a bit smaller. 有什么办法可以使这段代码更小一些。 I was thinking to just have the number 14 or 18 as a variable but I am not sure the best way to code if I should use if-else or some other way. 我当时想将数字14或18用作变量,但是我不确定是否应该使用if-else或其他方式来编码的最佳方法。

You could use a static dictionary as a map instead of a switch-statement. 您可以使用静态字典作为映射而不是开关语句。

 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;
 }

However, I would only do this, if there are really a lot of mappings that maybe can even be "read" from an external source like a configuration file. 但是,如果确实有很多映射甚至可以从外部源(例如配置文件)“读取”,我只会这样做。

Also note, that if the "key" is really a consecutive sequence of integers starting at 0, you might be able to use an array, where the "key" is simply the index into it. 还要注意,如果“键”实际上是从0开始的连续整数序列,则您可能可以使用一个数组,其中“键”只是其中的索引。

 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;
 }

Otherwise rather stay with an explicit switch statement (possibly factoring out the assignment for more terse code): 否则,宁愿使用显式的switch语句(可能将赋值分解为更简洁的代码):

 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;

It seems that there is some relationship between "00"->"14" and "01"->"18". 似乎“ 00”->“ 14”和“ 01”->“ 18”之间存在某种关系。 I believe this relationship results from the business logic. 我相信这种关系是业务逻辑的结果。 You should wrap the logic and make the code in your controller clear. 您应该包装逻辑并清除控制器中的代码。 Finally the code in the controller should look like: 最后,控制器中的代码应如下所示:

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;
    }
}
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;

I use mapping extensions fot that kind of code: 我使用此类代码的映射扩展:

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

and in your case this method: 在您的情况下,此方法:

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

I use this. 我用这个 You could easily change it to generic or use eg object[] instead. 您可以轻松地将其更改为泛型或使用例如object []代替。 Not super efficient, but very compact: 效率不高,但非常紧凑:

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;
    }
}

Then just call that like this: 然后像这样调用它:

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

Best of luck! 祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM