代码之家  ›  专栏  ›  技术社区  ›  Edward Tanguay

如何最好地将vb6“选择案例1067转换为2938…”转换为c_?

  •  5
  • Edward Tanguay  · 技术社区  · 15 年前

    我正在将一些vb6逻辑转换为c,并遇到了以下select/case语句。

    Select Case ZipCode
    Case 1067 To 19417, 35075 To 35085, 48455 To 48465, 55583 To 55596, 67480 To 67551, 75392, 85126, _
        93047 To 93059, 21217 To 21739, 35091 To 35096, 48480, 55606 To 55779, 67655 To 67707, 76726 To 76835, _
        85221 To 87679, 94315 To 94419, 22844 To 25799, 35102, 48488, 56154 To 56254, 67731 To 67759, 76855 To 76889, _
        87719 To 88339, 94428 To 94437, 25868, 35112, 48499 To 48531, 56271, 67824 To 67829, 77761, 88353, 94522, _
        25879, 35117, 48653, 56281 To 56299, 69427 To 69429, 77773 To 77776, 88361 To 88364, 94553, 26121 To 26160, _
        35216 To 35282, 48720 To 48727, 56321 To 56337, 69437 To 69439, 78048 To 78126, 88368 To 88379, 94559, _
        26180 To 26215, 35287 To 35469, 49124 To 49356, 56410 To 56479, 70173 To 71287, 78136 To 79117, 88410, 95028 To 95032, _
        26316 To 26389, 35576 To 35768, 49406, 56575, 71332 To 71540, 80331 To 83313, 88481, 95111 To 95152, _
        26419, 36110, 49419, 56626 To 56648, 71546 To 71711, 83324 To 83362, 88529, 95176 To 95185, _
        26434 To 26441, 36304 To 36358, 49448, 56727 To 56745, 71720 To 72189, 83365 To 83379, 88633, 95188 To 95194, _
        26452, 36367 To 36369, 49453, 56751 To 57339, 72250 To 72417, 83413, 88662 To 90491, 95197
    

    我能想到的最好的转换是一系列if/then/else语句,它们映射每个范围,例如

    if((ZipCode >= 1067 && ZipCode <=19417) ||
       (ZipCode >= 35075 && ZipCode <=35085) ||
       ...
    

    或者有更好的方法,例如将这些范围值放入某种类型的哈希/数组/集合中?

    4 回复  |  直到 15 年前
        1
  •  5
  •   tster    15 年前

    假设您使用的是3.5或更高版本 ,并可以访问扩展方法:

    如果我有这么多的比较,我会为自己创造一个好方法:

    public static class IntUtils
    {
        public static bool InRange(this int value, int low, int high)
        {
            return value <= low && value <= high;
        }
    }
    

    然后使用它:

    if (zipCode.InRange(1067, 19417) ||
        zipCode.InRange(35075, 35085) || ...
    

    如果你没有3.5 或者您不想使用扩展方法:

    public static class IntUtils
    {
        public static bool InRange(int value, int low, int high)
        {
            return value <= low && value <= high;
        }
    }
    

    然后使用它:

    if (IntUtils.InRange(zipCode, 1067, 19417) ||
        IntUtils.InRange(zipCode, 35075, 35085) || ...
    
        2
  •  5
  •   PiRX    15 年前

    也许您可以在int上创建扩展方法,比如:

    private static bool Between (this int i, int lower, int upper)
    {
      return i >= lower && i <= upper;
    }
    

    在类似代码中使用它

    if ZipCode.Between(1067, 19417) || ZipCode.Between(35075, 35085) || ...
    

    其他想法

    如果您基于此进行处理,也许您可以使用这些行中的某些内容

    Dictionary<int[], Action> actionMap = new Dictionary<int[], Action>
    {
      {new[]{1067,19417}, ProcessA},
      {new[]{35075, 35085}, ProcessB}
    };
    
    public void ProcessA()
    {
      // do something;
    }
    
    public void ProcessB()
    {
      // do something else;
    }
    
    public void Process(int zipCode)
    {
      var action = actionMap.FirstOrDefault(a => zipCode >= a.Key[0] && zipCode <= a.Key[1]);
      if (action.Value != null)
      {
         action.Value();
      }
    }
    

    P.S.不确定这是100%的工作代码,从我的头上写下来 P.P.S.特里亚德,现在我很确定它起作用了。

        3
  •  2
  •   Sjoerd    15 年前

    您描述的方法是从vb到c的文字转换。然而,这是如此多的数据,以至于在配置文件中比在代码中看起来更好。如果您这样做,最简单的方法可能就是简单地用zipcodes遍历列表并逐个比较它们。

    一种更有效的方法是对zipcodes进行排序并进行二进制搜索,或者使用散列函数或类似的方法,但如果这成为性能瓶颈,我会感到惊讶。

        4
  •  0
  •   Patrick    15 年前

    如果您想让一些给定的方法更抽象一点,可以使用如下扩展方法:

    public static class Utils
    {
        public static bool InRange<T>(this T value, T low, T high) where T : IComparable
        {
            return low.CompareTo(value) <= 0 && high.CompareTo(value) >= 0;
        }
    }