2010-04-12 20 views
4

使用C#,如果在功能C()之前調用了功能A(),我需要做一些額外的工作。如果在A()C()之間調用任何其他函數,那麼我不想做那些額外的工作。任何想法都需要最少量的代碼重複?如何在C#中調用其他方法時自動重置布爾值?

我試圖避免將flag = false;這樣的行添加到每個函數B1 .. BN中。

這是一個非常簡單的例子:

bool flag = false; 

void A() 
{ 
    flag = true; 
} 

void B1() 
{ 
    ... 
} 

void B2() 
{ 
    ... 
} 

void C() 
{ 
    if (flag) 
    { 
     //do something 
    } 
} 

上面的例子只是用一個簡單的例子,但我願意用比其他布爾東西。重要的是,我希望能夠設置和重置各種標誌,以便C()知道如何行爲。

謝謝你的幫助。如果您需要澄清,我將編輯我的文章。

+1

是否有多個線程正在呼叫A?即這是否需要線程安全? – womp 2010-04-12 23:05:25

回答

1

我解決了一個類似的情況(即需要知道A是否在C之前直接調用)的問題,方法是配置一個簡單的狀態機。實質上,我使用枚舉和一個屬性來管理/查詢狀態,從而構建了一個狀態對象。

當我調用A()的等價物時,它會將業務邏輯塊存儲爲指示A被調用的狀態。如果調用其他方法(你的B),它會將狀態切換到其他幾個狀態之一(我的情況有點複雜),然後當C()被調用時,查詢業務邏輯塊以確定我們是否打算調用一些方法D(),該方法持有「只有A被稱爲」功能。

我懷疑有多種方法可以解決這個問題,但我喜歡我採用的狀態機方法,因爲它允許我擴展最初的二進制情況以處理更復雜的多狀態情況。

我很幸運,在我的情況下,多線程不是問題,因爲這樣會使事情變得更有趣,但狀態機也可能在這種情況下工作。

只是我的兩分錢。這樣

A(); 

...語法:

+0

事實證明,我能夠使用類似的東西解決它。我使用枚舉並找到了一個不需要耦合函數A()和C()的更清晰的解決方案。 – gtaborga 2010-04-13 16:03:55

7

爲什麼不只是將「額外工作」分解爲一個記憶功能(即緩存結果)?每當你需要這項工作時,你只需調用這個函數,如果緩存是新鮮的,它將會短路。無論何時該工作變得陳舊,都會使緩存失效。在你上面相當奇怪的例子中,我假設你需要在每個B中有一個函數調用,而在C中有一個函數調用。調用A將會使緩存失效。

如果你正在尋找周圍(即一些聰明的方式來捕捉所有函數調用並插入此調用),我真的不會打擾。我可以想象一些瘋狂的運行時反射代理類的生成,但你應該讓你的代碼流清晰明瞭;如果每個函數都依賴於已完成的工作,則可以在每個函數中調用「doWork」。

+0

是的,我想有沒有簡單的方法來做到這一點。可以按任何順序調用函數。它只是需要額外工作的A(),C()的特定順序,但是如果我在A()中設置了一個標誌,並且在調用B1()或B2()時不重置它,那麼在C()我得到不正確的行爲。 – gtaborga 2010-04-12 23:12:42

+1

+1供參考反射;和「瘋狂」標籤,在這種情況下非常準確;) – 2010-04-12 23:23:14

3

如果您調用一種方法改變另一種方法的行爲,您必須確保以正確的順序調用它們,您的設計聽起來就會過於緊密。這是一面重要的紅旗。

聽起來像一些重構是爲了。提供建議而不看到更多的真實代碼是有點棘手的,但這裏有一個正確的方向。

考慮增加一個參數到C像這樣:

void C(bool DoExtraWork) { 
    if (DoExtraWork)... 
} 

課程「DoExtraWork」應該命名的東西在來電者是有意義的。

+0

我已經看到了類似的編碼模式,並且*在某些情況下*,它們是合理的。畢竟,有一個方法的行爲取決於它的類的狀態*是合理的:P – 2010-04-12 23:25:31

0

我並不推薦這樣做,但什麼是地獄:如果你願意,以取代所有簡單的方法調用

// _lastAction is a class-level Action member 
(_lastAction = new Action(A)).Invoke(); 

...那麼C()裏面你可以做一個檢查這樣的:

void C() 
{ 
    if (_lastAction.Method.Name == "A") 
    { 

    } 
} 

這可能不是THRE廣告安全(並且它不會在通過混淆器運行的代碼中運行而沒有一點修補),所以我不會在沒有經過嚴格測試的情況下使用類似的東西。我也不會使用像這樣的時期。

注:我的古代版的C#只有Action<T>(而不是ActionAction<T, T>等),所以如果你被困在那裏,太,你不得不一個虛擬參數添加到每個方法使用這種方法。

+0

我同意這種東西是混亂的地獄。我當時沒有想到一個好的解決方案,但是我發現了一個沒有混亂的工作。感謝你付出的努力。 – gtaborga 2010-04-13 16:05:10

相關問題