2011-05-11 211 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可能会导致各种烦人,难以追查的问题(因为你没有记录异常)。

相关问题