2011-05-11 248 views
8

考慮以下功能:有沒有更好的方法來處理轉換異常?

public enum Operator 
{ 
    EQUAL = 1, 
    GREATER_THAN = 2 
} 

public class checkString 
{ 
    public static bool isValid(string inputString, string checkString, Operator operation) 
    { 
     switch (operation) 
     { 
      case Operator.EQUAL: 
       if (inputString == checkString) 
        return true; 

       break; 

      case Operator.GREATER_THAN: 

       // Numeric check for greater than 
       try 
       { 
        double inputDouble, checkDouble; 

        inputDouble = Convert.ToDouble(inputString); 
        checkDouble = Convert.ToDouble(checkString); 

        if (inputDouble > checkDouble) 
         return true; 
       } 
       catch (Exception) 
       { } 

       // Date check for greater than 
       try 
       { 
        DateTime inputDate, checkDate; 

        inputDate = DateTime.Parse(inputString); 
        checkDate = DateTime.Parse(inputString); 

        if (inputDate. > checkDate) 
         return true; 
       } 
       catch (Exception) 
       { } 

       break; 
     } 
     return false; 
    } 
} 

參數

  • inputString:我們要評估
  • checkString什麼:輸入必須評估對
  • 運營商的標準(值):枚舉我們要執行的操作

其他的事情知道

  • 在一個文件中的每一行對這種方法計算返回如果條件已滿足
  • 評估由行的文件檢查線記錄的過程中,一個實例它等於條件。它也可能檢查同一條線是否也比條件更大。一旦檢查完成後,它移動到下一個記錄
  • 沒有其他的事件偵聽器迷上了比任何違約到位,我不推額外的數據來調試或跟蹤日誌等

問題

在這個過程的任何時刻,我都不知道人們將要評估的是什麼,但我需要能夠檢查「某事」(不管是什麼)等於,大於或小於其他事物。當然,我檢查其他的東西,但我已經大大簡化了這個功能。

也就是說,使用EQUAL或NOT_EQUAL可以快速運行,可以非常快速和高效地根據所述標準在非常大的文件中處理記錄。一旦我添加GREATER_THAN邏輯,它的速度就會很慢......直到需要花費數分鐘來處理過去花費半分鐘時間的20兆文件。

從我可以告訴:

  • 拋出異常所有的地方。不能保證字段將是數字或日期類型。所以,我必須嘗試轉換爲這些數據類型來試圖評估條件
  • 當異常被拋出時,控制檯獲取在那裏我有沒有指示它這樣做的輸出,它的那種自動

是的,我在這方面缺乏經驗,並且希望更多地瞭解異常處理以及幕後真正發生的事情,因爲當其他80%的記錄不是數字時,這就是20兆,8萬記錄中的很多例外文件。

有更好的方法來處理演員本身以提高效率嗎?我已經看到double.Parse/TryParse,並且可以直接投射在前面,但我不確定哪個最有利。

回答

8

您可以在這些數據類型上使用TryParse()。例外是雜亂和昂貴的。 TryParse將返回真/假,如果它工作或不,而不拋出異常。所以你可以檢查通話結果。比例外更有效。

Convert.ToDouble()和Double.Parse()會拋出異常。

試試這個代碼。這是不是最好的,但它比你現在考慮你不知道的類型可能是有什麼更好的:

public static bool isValid(string inputString, string checkString, Operator operation)  
     {   
      double dblTmp1; 
      double dblTmp2; 

      if (Double.TryParse(inputString, out dblTmp1) && double.TryParse(checkString, out dblTmp2)) 
      { 
       return Compare<Double>(dblTmp1, dblTmp1, operation); 
      } 

      DateTime dtTmp1; 
      DateTime dtTmp2; 
      if (DateTime.TryParse(inputString, out dtTmp1) && DateTime.TryParse(checkString, out dtTmp2)) 
      { 
       return Compare<DateTime>(dtTmp1, dtTmp2, operation); 
      } 

      throw new InvalidOperationException("Unknown type"); 

     } 

     public static bool Compare<T>(T obj1, T obj2, Operator operation) where T : IComparable  
     { 
      switch (operation) 
      { 
       case Operator.EQUAL: 
        { 
         return obj1.Equals(obj2); 
        } 
       case Operator.GREATER_THAN: 
        { 
         return obj1.CompareTo(obj2) > 0; 
        } 
       default: 
        { 
         throw new InvalidOperationException("Unknown operation"); 
        } 
      } 
     } 
+0

哇,這是一個非常優雅的泛型使用...我印象深刻。很高興看到從轉換中提取的比較 – Mohgeroth 2011-05-11 23:31:42

+0

太棒了!它是如此真棒。 – Justin 2011-05-12 03:51:58

+1

執行單個文件所花費的時間,現在可以處理超過120個文件(每個文件5至30個兆字節),而不是每條線上評估的超過200個規則。使這個我最喜歡的答案的獎金片是通用方法。對我來說,它是一個很好的觀點,說明泛型方法屬於哪裏...這不是我最強大的領域,儘管我理解它們是如何工作的,但當你不熟練時很難看到它們適合的地方。感謝這個知識,一個很好的答案:) – Mohgeroth 2011-05-12 15:59:23

2

請記住,使用異常減慢你的程序,因爲幕後的運行時創建一個異常堆棧以便能夠放鬆這種情況下的例外是拋出。不管你的程序是否拋出,這個堆棧都會被維護,而這個開銷是最讓你失望的。

+0

至少我的想法是在正確的位置,感謝技術細節!這是我在解決我的問題時想要學習的一大塊內容:) – Mohgeroth 2011-05-11 23:34:48

0

其他答案可能是這種情況下的最佳解決方案,但在一般情況下,您可以通過捕獲特定異常(可能是NumberFormatExceptionClassCastException)來改進解決方案。捕獲Exception可能會導致各種煩人,難以追查的問題(因爲你沒有記錄異常)。

相關問題