2010-08-27 57 views
5

我正在將一些VB6邏輯轉換爲C#並遇到以下SELECT/CASE語句。如何將VB6「Select Case 1067 To 2938 ...」轉換爲C#?

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) || 
    ... 

或者還有更好的方法,例如,有些方法可以將這些範圍值放在某種哈希/數組/集合中?

+2

看起來像「從移動硬編碼的配置值一個完美的情況下,源代碼寫入配置文件「。無論如何,當觸摸代碼是必要的時候,我會避免重新實現這個怪物。 – Tomalak 2010-08-27 13:09:07

+0

是的,我同意。此代碼不應該按原樣轉換! – tster 2010-08-27 13:12:53

+1

這讓我頭痛。 – 2010-08-27 13:15:17

回答

5

假設你使用的是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) || ... 
+0

您已將'this'留在您的非擴展方法示例中,應該是 public static bool InRange(int value,int low,int high) – stuartd 2010-08-27 13:15:51

+0

@Stuart,謝謝修正。 – tster 2010-08-27 13:18:05

5

也許你可以在如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(); 
    } 
} 

附:不知道這是100%的工作代碼,從頭頂上寫下來 p.p.s. Triead,現在我很確定它正在工作

+0

偉大的思想家一樣想法;) – tster 2010-08-27 13:09:15

+0

@tster,似乎如此:) – PiRX 2010-08-27 13:10:22

2

您描述的方法是從VB到C#的文字轉換。但是,這是如此之多的數據,以至於在配置文件中比在代碼中更好。如果你這樣做,最簡單的方法可能就是簡單地用zipcodes循環列表並逐一比較它們。

更有效的方法是對郵編進行排序並進行二進制搜索,或者使用散列函數或類似的東西,但如果事實證明這是一個性能瓶頸,我會感到驚訝。

0

如果你想做出一些給定的辦法多一點抽象,您可以用擴展方法像這樣去:

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