2016-10-03 225 views
1

我有下面的基類和派生類。有2點,我覺得我的代碼有問題:c#避免拳擊和重複代碼

public class FieldCollection 
{ 
    public FieldCollection() 
    { 
     Fields = new List<FieldBase>(); 
    } 

    public List<FieldBase> Fields { get; set; } 

    public void InitFieldList() 
    { 
     foreach (var item in DbFieldList) 
     { 
      if (item.Type == FieldTypes.int) 
      { 
       Fields.Add(new Field<int>()); 
      } 
      else 
      if (item.Type == FieldTypes.string) 
      { 
       Fields.Add(new Field<string>()); 
      } 
      ... 
     }; 
    } 

    public void SetFieldValue(string fieldName, object value) 
    { 
     FieldBase field = FindField(fieldName); 

     if ((field as FInt) != null) 
     { 
      (field as FInt).SetValue(Convert.ToInt32(value)); 
     } 
     else 
     if ((field as FString) != null) 
     { 
      (field as FString).SetValue(Convert.ToString(value)); 
     } 
     else 
     if ((field as FDate) != null) 
     { 
      (field as FDate).SetValue(Convert.ToDateTime(value)); 
     }; 
    } 

    public FieldBase FindField(string fieldName) 
    { 
     FieldBase field = Fields.FirstOrDefault(f => (String.Equals(f.Name, fieldName, StringComparison.CurrentCultureIgnoreCase))); 

     return field; 
    } 
} 

public abstract class FieldBase 
{ 
    public string Name { get; set; } 
} 

public class FInt : FieldBase 
{ 
    public void SetValue(int value) 
    { 
    } 
} 

public class FString : FieldBase 
{ 
    public void SetValue(string value) 
    { 
    } 
} 

public class FDate : FieldBase 
{ 
    public void SetValue(DateTime value) 
    { 
    } 
} 
  1. 重複:如果未來出現了一個新的派生類,我將有額外的if語句等補充。
if ((field as FInt) != null) 
{ 
    (field as FInt).SetValue(Convert.ToInt32(value)); 
} 
else 
if ((field as FString) != null) 
{ 
    (field as FString).SetValue(Convert.ToString(value)); 
} 
else 
if ((field as FDate) != null) 
{ 
    (field as FDate).SetValue(Convert.ToDateTime(value)); 
}; 
  • 裝箱和取消裝箱:我被迫對象值轉換爲基於派生的類的類型的期望類型:
  • (field as FInt).SetValue(Convert.ToInt32(value)); 
    (field as FString).SetValue(Convert.ToString(value)); 
    (field as FDate).SetValue(Convert.ToDateTime(value)); 
    

    我對如何設計這些類以克服上述提及感興趣編輯問題。

    您的幫助非常感謝。

    +0

    看起來你需要仿製藥 –

    回答

    3

    您可以通過重寫使用泛型代碼一次(代碼重複和拳擊),解決這兩個問題:

    public class FieldCollection 
    { 
        public FieldCollection() 
        { 
         Fields = new List<FieldBase>(); 
        } 
    
        public List<FieldBase> Fields { get; set; } 
    
        public void SetFieldValue<T>(string fieldName, T value) 
        { 
         var field = FindField<T>(fieldName); 
    
         field.SetValue(value); 
        } 
    
        public Field<T> FindField<T>(string fieldName) 
        { 
         return Fields.OfType<Field<T>>() 
          .FirstOrDefault(f => (String.Equals(f.Name, fieldName, StringComparison.CurrentCultureIgnoreCase))); 
        } 
    } 
    
    public abstract class FieldBase 
    { 
        public string Name { get; set; } 
    } 
    
    public class Field<T> : FieldBase 
    { 
        public void SetValue(T value) 
        { 
        } 
    } 
    

    InitFieldList,你可以使用lambda表達式的字典。例如:

    private Dictionary<FieldTypes, Func<FieldBase>> FieldInitializers = new Dictionary<FieldTypes, Func<FieldBase>> 
    { 
        { FieldTypes.int,() => new Field<int>() }, 
        { FieldTypes.string,() => new Field<string>() } 
    } 
    

    然後,它只是一個瀏覽你的字典的事:

    public void InitFieldList() 
    { 
        foreach (var item in DbFieldList) 
        { 
         Fields.Add(FieldInitializers[item.Type].Invoke()); 
        } 
    } 
    
    +0

    感謝@KooKiz。我忘了在FieldCollection類中添加Fields屬性的population方法。我也想問如何避免多個if語句?請參閱原始帖子中的修改。 – Tim

    +0

    @Tim請編輯你的問題,而不是答案。此外,請確切指出條件是 –

    +0

    編輯。謝謝。 – Tim