2011-11-17 79 views
0

知道是否有使用泛型方法,使其更加优雅和消除类型名称开关重构这个工作代码“开关”语句的好方法:C#3.5重构方法使用泛型方法

 private void CreateFragDetailsHistoryLogEntry(string field, FRAGMENT_ANALYSIS fragment, ModifiedMemberInfo info, RegistriesLinqDataContext context, string analyteName) 
     { 
       LABRESULT_CHANGE_TRACKING tracking = new LABRESULT_CHANGE_TRACKING(); 

       string originalValue = null, newValue = null; 

       var typeName = info.OriginalValue == null ? info.CurrentValue.GetType().Name : info.OriginalValue.GetType().Name; 

       switch (typeName) 
       { 
        case "DateTime": 

         originalValue = (info.OriginalValue as DateTime?).HasValue ? String.Empty : (info.OriginalValue as DateTime?).Value.ToShortDateString()); 
         newValue = (info.CurrentValue as DateTime?).HasValue ? String.Empty : (info.CurrentValue as DateTime?).Value.ToShortDateString()); 
         break; 

        case "String": 

         originalValue = info.OriginalValue.ToString(); 
         newValue = info.CurrentValue.ToString(); 
         break; 

        case "Boolean": 

         originalValue = (bool)info.OriginalValue ? "True" : "False"; 
         newValue = (bool)info.CurrentValue ? "True" : "False"; 
         break; 

        case "Char": 
         originalValue = ((char?)info.OriginalValue).HasValue ? (char?)info.OriginalValue == 'Y' ? "True" : "False" : "False"; 
         newValue = ((char?)info.CurrentValue).HasValue ? (char?)info.CurrentValue == 'Y' ? "True" : "False" : "False"; 
         break; 
       } 
       tracking.CHANGE_DESCRIPTION = @"Fragment #" + fragment.FRAGMENT_ID_NUMBER + @" field """ + field + @""" changed from """ + originalValue 
        + @""" to """ + newValue + @"""."; 
       tracking.CHANGE_FIELD = "Fragment Details"; 
       break;    

     tracking.SetAsInsertOnSubmit(); 

     LabResultsTrackingManager manager = new LabResultsTrackingManager(); 

     manager.Update(tracking); 

    } 

此方法创建并向数据库写入对现有LINQ实体的更改。

+1

这是codereview.stackexchange的问题。 com,而不是StackOverflow。 –

+4

@Judah wtf是codereview?为什么我们不能讨论SO上的代码模式和代码风格?这太荒谬了:o) – stefan

+0

@stefan StackOverflow适用于可以有明确答案的问题。这个问题 - “我如何重构我的蹩脚代码” - 是主观的。这更适合http://codereview.stackexchange.com –

回答

4

至少有三种可能的解决方案。

  1. 使用的if/else链:

    var type = info.OriginalValue == null ? info.CurrentValue.GetType() : info.OriginalValue.GetType(); 
    
    if (type == typeof(DateTime)) 
    { 
        ... 
    } 
    else if (type == typeof(string)) 
    { 
        ... 
    } 
    ... 
    
  2. 使用动态调度

    dynamic dynamicThis = this; 
    var result = dyanmicThis.ConvertValues(info.OriginalValue, info.CurrentValue); 
    originalValue = result.Item1; 
    newValue = result.Item2; 
    
    ... 
    
    Tuple<object, object> ConvertValues(DateTime? originalValue, DateTime? currentValue) 
    { 
        return Tuple.Create(originalValue != null ? originalValue.Value.ToShortDateString() : "", currentValue != null ? currentValue); 
    } 
    
    Tuple<object, object> ConvertValues(string originalValue, string currentValue) 
    { 
        return Tuple.Create(originalValue, currentValue); 
    } 
    

    该解决方案采用了动态语言运行时接在运行时,正确的方法重载,因此它不是没有性能成本。尽管除非它被称为lot它可能是无关紧要的。

  3. 最后,有你也可以的Dictionary<Type, Action>字典并填充了一堆在你的逻辑链实现每个选择的lambda表达式:

    var dictionary = new Dictionary<Type, Action>(); 
    dictionary[typeof(DateTime?)] =() => { 
        originalValue = (info.OriginalValue as DateTime?).HasValue ? String.Empty : (info.OriginalValue as DateTime?).Value.ToShortDateString()); 
        newValue = (info.CurrentValue as DateTime?).HasValue ? String.Empty : (info.CurrentValue as DateTime?).Value.ToShortDateString()); 
    }; 
    dictionary[typeof(string)] =() => { 
        originalValue = info.OriginalValue.ToString(); 
        newValue = info.CurrentValue.ToString();   
    }; 
    var type = info.OriginalValue == null ? info.CurrentValue.GetType() : info.OriginalValue.GetType(); 
    dictionary[type](); // Invoke the appropriate lambda 
    
+1

感谢您的回复。我喜欢第二个解决方案,但不幸的是,因为我在3.5中,所以不能使用它。可能最终会使用第三种方法 – Victor