2014-01-21 47 views
0

這是一個重構問題。如何合併具有相同主體但簽名不同的方法?

如何將所有這些Check()方法合併爲一個Generic Check()方法,因爲它們的方法體是相同的?

ppublic class ChangeDetector : IChangeDetector 
{ 
    private readonly IEqualityHelper _equalityHelper; 

    public ChangeDetector(IEqualityHelper equalityHelper) 
    { 
     _equalityHelper = equalityHelper; 
    } 

    public bool ChangeDetected { get; private set; } 

    public void Check<T>(IList<T> existingList, IList<T> newList) where T : IdentifiedActiveRecordBase<T>, new() 
    { 
     if (!this._equalityHelper.Equals(existingList, newList)) 
     { 
      NotifyChange(); 
     } 
    } 

    public void CheckEntities<T>(IdentifiedActiveRecordBase<T> existingObj, IdentifiedActiveRecordBase<T> newObj) where T : IdentifiedActiveRecordBase<T>, new() 
    { 
     if (!this._equalityHelper.Equals(existingObj, newObj)) 
     { 
      NotifyChange(); 
     } 
    } 

    public void Check(string existing, string newVal) 
    { 
     if (!this._equalityHelper.Equals(existing, newVal)) 
     { 
      NotifyChange(); 
     } 
    } 

    public void Check<T>(T existing, T newVal) where T : struct 
    { 
     if (!this._equalityHelper.Equals(existing, newVal)) 
     { 
      NotifyChange(); 
     } 
    } 

    public void Check<T>(T? existing, T? newVal) where T : struct 
    { 
     if (!this._equalityHelper.Equals(existing, newVal)) 
     { 
      NotifyChange(); 
     } 
    } 

    private void NotifyChange() 
    { 
     ChangeDetected = true; 
    } 
} 

我EqualityHelper類成員具有不同的身體,雖然這是很好的:

public class EqualityHelper : IEqualityHelper 
    { 
     public bool Equals<T>(IList<T> existingList, IList<T> newList) where T : IdentifiedActiveRecordBase<T>, new() 
     { 
      if (existingList == null || existingList.Count == 0) 
      { 
       if (newList != null && newList.Count > 0) 
       { 
        return false; 
       } 
      } 
      else 
      { 
       if (newList == null 
        || existingList.Count != newList.Count 
        || newList.Any(newListItem => existingList.Any(existingListItem => existingListItem.Id == newListItem.Id))) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 

     public bool Equals<T>(IdentifiedActiveRecordBase<T> existingObj, IdentifiedActiveRecordBase<T> newObj) where T : IdentifiedActiveRecordBase<T>, new() 
     { 
      if (existingObj == null) 
      { 
       if (newObj != null) 
       { 
        return false; 
       } 
      } 
      else 
      { 
       if (newObj == null || existingObj.Id != newObj.Id) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 

     public bool Equals(string existing, string newVal) 
     { 
      return string.Equals(existing, newVal); 
     } 

     public bool Equals<T>(T existing, T newVal) where T : struct 
     { 
      return !existing.Equals(newVal); 
     } 

     public bool Equals<T>(T? existing, T? newVal) where T : struct 
     { 
      if ((existing.HasValue && !newVal.HasValue) 
       || (!existing.HasValue && newVal.HasValue) 
       || existing.Equals(newVal)) 
      { 
       return false; 
      } 

      return true; 
     } 
    } 
+0

這可能嗎?我的意思是,我真的不知道,你似乎比我有更多的經驗,但我的第一個猜測是,身體不是真的一樣?身體內部的簽名都會有所不同,因爲他們正在使用的變量「現有」本身沒有相同的簽名?也許只是宣佈它是動態的?但是如果你聲明它是動態的,那麼如果我沒有弄錯的話,你會獲得一個性能上的提升,因爲這是遲到的約束。 –

+0

不知道,也許不可能。我只看到了可能被合併的重複身體。 –

回答

1

只是因爲該方法機構正在尋找類似不代表方法簽名可以合併。您的五個Handle方法都會調用五個不同的Equals-方法,因此除非您可以合併五個Equals方法,否則不能合併Handle方法。你當然不能那樣做,因爲Equals方法的實現是不同的。請記住,要調用哪個Equals-method是編譯時決定的,而不是運行時。

編輯:什麼你可能做的是改變兩個Handle/CheckEquals的簽名Check(object existing, object equals)Equals(object existing, object equals)。然後在Equals -method中執行一個運行時類型檢查,該類型檢查可以通過類型轉換的幫助將結果切換到您已有的五個Equals方法。這會使執行速度變慢,只能說是更可維護。我不確定我會走下那條路。

+0

因爲他們的身體不同,我無法明確地合併所有Equals方法。 –

+1

引擎蓋下的五個Handle方法也是如此。他們編譯成五個不同的方法調用。 – Nilzor

1

方法體並不完全相同,因爲它們都調用了不同的Equals()方法。你打算做的(如果我正確地理解了這個問題)將完成一個Handle<T>()方法,其中T可以是任何類型。考慮你想要在代碼中表達什麼,如果你有一個Handle<T>()方法,應該能夠調用一個方法Equals<T>()。這樣,你可以實現你的處理邏輯一次(並且可能以後這變得更復雜,但你只需要編寫一次),並且將比較對象的棘手的業務委託給你的相等比較器類。

+0

是的,這是一個問題。 –

+0

當不是所有的Handle方法都是通用的,並且並非所有的泛型方法都具有相同的約束時,您無法脫離一個Handle 。 – Nilzor

相關問題