2011-06-10 128 views
0

我有一個enum DoStuff,其值爲before,afternone。這些名字並不是真正的名字,但它可以說明問題。該班級有一個方法foo有沒有更好的方式來編寫這段代碼?

下面是一組只讀屬性,不同類型的,每個看起來如下:

public [type] MyProperty { 
    get { 
     if(enumValue == DoStuff.Before) 
      foo(); 

     [type] result = //Do calculations here 

     if(enumValue == DoStuff.After) 
      foo(); 

     return result; 
    } 
} 

有抽象這些前/後計算召喚出來的一種方式?我現在能想到的兩種解決方案:

  • 創建需要一個委託,並在適當的地方調用foo的私有方法。複雜的平臺上缺乏泛型我寫這個。

  • 讓既沒有包裝調用一個不可基類,並從中獲得一個前和子類訪問基類的屬性,與呼叫在適當的地方

後是否有一個衆所周知的模式對於這種結構?

+2

作爲對風格的一般評論,除了初始化目的外,我會避免更改屬性getter中的狀態。 – Reddog 2011-06-10 20:37:05

+1

無限遞歸! – 2011-06-10 20:38:55

+0

@丹濤:哎呀。我的錯。 – Eric 2011-06-10 20:42:49

回答

1

請用這個語法的方法:

delegate void Handler(); 

void DoHandler(Handler handler) 
{ 
     if(enumValue == DoStuff.Before) 
      foo(); 

     handler(); 

     if(enumValue == DoStuff.After) 
      foo(); 
} 

然後在你的財產

public [type] MyProperty 
{ 
    get 
    { 
     [type] result = default(type); 
     DoHandler(() => 
     { 
      int a = 5; 
      int b = 6; 
      result = a + b; 
     }); 
     return result; 
    } 
} 
+0

有兩個問題。首先,這要求我爲每種類型的返回值編寫一個'DoHandler'函數,這會使代碼更加混亂,而不是更清晰。其次,我在問題中說過我沒有泛型支持,所以沒有'Func '。 – Eric 2011-06-11 19:45:27

+0

好吧,你可以做得稍微不同。我會修改它。 – 2011-06-11 20:19:02

+0

你可以在c#中的lambdas中進行閉包嗎? – Eric 2011-06-11 21:27:56

0

我會傾向於在適當的地方創建Before and After事件/委託並將foo()放在適當的位置,可能無論您在哪裏設置enumValue。然後致電:

get { 
    BeforeDelegate(); 
    // Do calcs 
    AfterDelegate(); 
} 

什麼是實際用途?你爲什麼需要這種模式?

旁註:如果我有一個吸氣劑做這種邏輯我更可能把它放在一個方法。這不太可能讓人感到驚訝。方法暗示我可能做了一些事情來獲得你所要求的價值,而不僅僅是暴露一個標量值。

+0

代碼是與一個硬件接口,所以使用屬性似乎是合理的(因爲它們是硬件的屬性)。 [硬件](http://www.sparkfun.com/datasheets/Components/HMC6352.pdf)有三種模式:連續更新('Continuous',又名'DoStuff.None'),在請求時更新('Standby',又名'DoStuff.Before'),並在讀取後更新('Query',又名'DoStuff.After')。 – Eric 2011-06-10 20:41:19

+0

嗯......我仍然更喜歡'GetPropertyValue()'調用,但這是一個挑剔的事情開始。在決策點中是否還有其他的「foo()」?我不認爲這是一個「最好的模式」問題,而是一個「簡潔的語義學」的東西。如果發生了這一切,並且這是它發生的唯一屬性,那麼枚舉方法非常清晰。如果這種情況發生,我會傾向於採用委託/事件方法。 – 2011-06-10 22:20:32

0

我認爲它能夠更好地把枚舉值中有一個名爲EnamumValue和事件前後1個屬性一個單獨的類,並處理這事件在使用enamvalue類的類, 當enumvalue變化觸發相應的事件

public class EnumValueClass 
{ 

    public event BeforeDelegate OnBefore(); 
    public event AfterDelegate OnAfter(); 
    private EnumType enumValue; 
    public EnumType EnumValue 
    { 
     get { 
      return enumValue; 
     } 
     set{ 
      this.enumValue = value; 
      if(enumValue == DoStuff.Before) 
       if(OnBefore!=null) 
        OnBefore(); 

      if(enumValue == DoStuff.After) 
       if(OnAfter!=null) 
        OnAfter(); 
     } 


    } 
} 
+0

這不符合通話合約。首先,'OnAfter'和'OnBefore'具有相同的功能。更重要的是,'foo'方法必須在大多數屬性訪問之前或之後調用。當模式改變時不需要調用它。 – Eric 2011-06-11 07:58:34

相關問題