2014-12-03 82 views
1

首先,如果已經詢問過,請致歉。我很難將問題轉化爲文字。所以如下面的代碼片段所示,我有一個接口ISomeInterface,它有一個功能CalculateSomething,它的參數爲ICalculationInput。我有多種類型實現ISomeInterface,並且每個實現都需要與CalculateSomething略有不同的參數。因此CalculateSomething接受ICalculationInput而不是具體參數。現在在函數CalculateSomething的每個實現中,在使用它之前,我不得不將它強制轉換爲特定類型,這會使代碼變得有點難看。我想聽聽你對如何重新設計這個問題的意見,所以我不需要投入參數,所以我可以避免運行時錯誤,並且在幾年後再次讀取我的代碼時不會感到尷尬。在功能接受基本類型中處理der types類型

interface ISomeInterface 
{ 
    void CalculateSomething(ICalculationInput input); 
} 

class SpecificClass : ISomeInterface 
{ 
    public void CalculateSomething(ICalculationInput input) 
    { 
     var spInput = ICalculationInput as SpecificInput; 
     if(spInput == null) throw ... 
    } 
} 
+0

爲什麼總是需要使用'SpecificInput'?然後將接口改爲'CalculateSomething(SpecificInput input)' – 2014-12-03 11:35:53

+0

如果你不會爲幾年前寫的代碼感到尷尬,那麼你的學習不夠充分......;) – 2014-12-03 11:36:06

+0

@TimSchmelter我有不同的ISomeInterface實現和每個實現有自己的輸入參數類型派生自ICalculationInput – v1p3r 2014-12-03 11:40:28

回答

2

如果SpecificClass通過設計不能有希望使比SpecificInput其他任何CalculateSomething工作,但通常它有一個CalculateSomething(SpecificInput)方法,而不是一個CalculateSomething(ICalculationInput)方法。有時會遇到實際問題,但這裏並不是這樣。如果ISomeInterface僅由該類實現,那很簡單:只需更改界面即可。否則,如果一些類需要一些特定的輸入級,和其他類需要一個不同的特定的輸入級,參數化:

interface ISomeInterface<T> 
{ 
    void CalculateSomething(T input); 
} 

class SpecificClass : ISomeInterface<SpecificInput> 
{ 
    public void CalculateSomething(SpecificInput input) 
    { 
     ... 
    } 
} 

可選的,如果它是有道理的,你可以添加一個where T : ICalculationInput約束你的界面。

如果因任何原因,你不能改變的接口,您仍然可以使用一個基類,提供的方法的一個常見的實現,這將是這個樣子:

interface ISomeInterface 
{ 
    void CalculateSomething(ICalculationInput input); 
} 

abstract class SomeInterfaceBase<T> : ISomeInterface 
{ 
    public abstract void CalculateSomething(T input); 

    void ISomeInterface.CalculateSomething(ICalculationInput input) 
    { 
     var concreteInput = input as T; 
     if (concreteInput == null) 
     { 
      if (input == null) 
       throw new ArgumentNullException("input"); 
      else 
       throw new ArgumentException("input must be a T", "input"); 
     } 
     CalculateSomething(concreteInput); 
    } 
} 

class SpecificClass : SomeInterfaceBase<SpecificInput> 
{ 
    public override void CalculateSomething(SpecificInput input) 
    { 
     ... 
    } 
} 

我懷疑有輕微上述錯誤,但這個概念應該是可行的。

+0

我最終使用的解決方案接近您的建議。謝謝! – v1p3r 2014-12-04 14:39:16