2016-05-16 70 views
-1

我有以下代碼完美地工作。然而,看着它讓我相信必須有一個更短,更優雅的方式。 Switch()顯然不是答案,所以我堅持嵌套if。縮短嵌套IFs

if (mode == 1) 
{ 
    if (distance <= 4000) 
    { 
     modeValue = "1F"; 
    } 

    else if (distance > 4000 && distance <= 8000) 
    { 
     modeValue = "2F"; 
    } 

    else if (distance > 8000 && distance <= 12000) 
    { 
     modeValue = "3F"; 
    } 

    else if (distance > 12000) 
    { 
     modeValue = "F 0-5"; 
    } 
} 

else if (mode == 2) 
{ 
    if (distance <= 500) 
    { 
     modeValue = ""; 
    } 

    else if (distance > 500 && distance <= 4000) 
    { 
     modeValue = "2F"; 
    } 

    else if (distance > 4000 && distance <= 8000) 
    { 
     modeValue = "3F"; 
    } 

    else if (distance > 8000 && distance <= 12000) 
    { 
     modeValue = "4F"; 
    } 

    else if (distance > 12000) 
    { 
     modeValue = "F 0-5"; 
    } 
} 

有什麼建議嗎?

+2

你應該在[CodeReview](http://codereview.stackexchange.com/)上試試這個問題 – Jonesopolis

+0

清理它的一種方法是對整個事物進行方法化。另一種做事的方式是根據你上面的邏輯,將包含一個方法的對象的屬性與距離屬性進行比較,以得出modeValue。不完全擺脫它,但確實使它更有組織。 –

+0

較短並不總是更好。如果代碼有效,很容易理解和維護,那麼您應該保持原樣。 – Nasreddine

回答

1

首先,你應該更換處理mode帶開關的if語句:通過將它們放置在一個方法

switch (mode) { 
case 1: 
    //... 
    break; 
case 2: 
    //... 
    break; 
default: break; 
} 

然後你就可以更換內部的if-else鏈與開關(是這些在C#中被稱爲「程序」?):

string Foo(int mode, int distance) { 
    switch (mode) 
    { // http://stackoverflow.com/users/469563/gendoikari Thanks for pointing out redundant comparisons 
    case 1: 
     if (distance <= 4000) 
     { return "1F"; } 
     else if (distance <= 8000) 
     { return "2F"; } 
     else if (distance <= 12000) 
     { return "3F"; } 
     else 
     { return "F 0-5"; } 
    case 2: 
     if (distance <= 500) 
     { return ""; } 
     else if (distance <= 4000) 
     { return "2F"; } 
     else if (distance <= 8000) 
     { return "3F"; } 
     else if (distance <= 12000) 
     { return "4F"; } 
     else 
     { return "F 0-5"; } 
    default: break; 
    } 

哦,看,不可思議的事發生在無意中!現在,只要您想更改modeValue,只需致電Foo即可!

modeValue = Foo(mode, distance); 
+0

現在這正是我期待的那種整潔的解決方案!謝謝,dorukayhan! – PeterJ

+0

雖然沒有真正編譯! (需要退貨的默認情況下) – Chris

+0

哦...感謝您的警告 – dorukayhan

2

有兩件事情:

首先,你有多餘的檢查,

else if (distance > 500 && distance <= 4000)

可能僅僅是else if (distance <= 4000)代替,因爲「其他人」的部分..你已經檢查距離> 500,如果你在其他地方。

其次,它確實取決於周圍的環境,但這可能是一個使用多個類的好地方。我將在這裏假設這全部在一個名爲CalculateModeValue的方法中,並且該方法位於名爲Calculator的類中。我也會假設「Mode == 1」的意思是「LongDistance」,而「Mode == 2」的意思是「ShortDistance」。

在這種情況下,我會有一個叫做Calculator的抽象類。然後,我將用2個獨立的類「LongDistanceCalculator」和「ShortDistanceCalculator」對它進行分類。 CalculateModeValue將是Calculator中的一個抽象方法,並在每個子類中分別實現。這樣,你不需要檢查「If Mode == 1」;每個類的實現將處理該模式的正確邏輯。

但同樣,這是對未知數做出假設;它真的取決於這些if語句的上下文。

+0

*它真的取決於這些if語句*的周圍環境。 –

1

使用嵌套ifs沒有什麼問題,就像你在那裏使用嵌套ifs一樣。 但是,如果你真的不想看他們,也許只需輸入一個方法中的邏輯,它接受一個模式變量,然後繼續將邏輯應用於模式的值?

創建這樣的子過程也可以在您的應用程序中重複使用以應用相同的計算。

0

好吧,首先,我只是做了,如果機構單行沒有括號,這會縮短它真正的好。你原來的代碼有一些小的調整看起來一樣好,因爲它可以恕我直言:

string Func1(int mode, double distance) 
{ 
    if(mode == 1) 
    { 
     if(distance <= 4000) 
      return "1F"; 
     else if(distance <= 8000) 
      return "2F"; 
     else if(distance <= 12000) 
      return "3F"; 
     else 
      return "F 0-5"; 
    } 
    else 
    { 
     if(distance <= 500) 
      return ""; 
     else if(distance <= 4000) 
      return "2F"; 
     else if(distance <= 8000) 
      return "3F"; 
     else if(distance <= 12000) 
      return "4F"; 
     else 
      return "F 0-5"; 
    } 
} 

如果你不喜歡的是,有一噸的做這件事的方式。如何:

class Mode 
{ 
    public double Distance; 
    public string Name; 
    public Mode(double d, string n) { this.Distance = d; this.Name = n; } 
} 

string Func(int mode, double distance) 
{ 
    Mode[] modes; 
    if(mode == 1) 
     modes = new Mode[] { new Mode(4000, "1F"), 
          new Mode(8000, "2F"), 
          new Mode(12000, "3F"), 
          new Mode(double.MaxValue, "F 0-5") }; 
    else 
     modes = new Mode[] { new Mode(500, ""), 
          new Mode(4000, "2F"), 
          new Mode(8000, "3F"), 
          new Mode(12000, "4F"), 
          new Mode(double.MaxValue, "F 0-5") }; 

    for(int pos = 0; ; pos++) 
     if(distance <= modes[pos].Distance) 
      return modes[pos].Name; 
} 

顯然你可以重用這些數組。或者你可以讓每個模式都帶有一個Predicate<T>或類似的東西,它指定了要選擇的模式的條件。我猜Mode可能只是一個KeyValuePair<TKey,TValue>以縮短一些。