使用泛型方法的C#3.5重构方法

时间:2011-11-17 23:07:13

标签: .net .net-3.5

想知道是否有一种很好的方法可以使用泛型方法重新考虑这个工作代码'switch'语句,使其更优雅并消除开关类型名称:

        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 个答案:

答案 0 :(得分: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