2009-12-28 144 views
3

我遇到了一個很容易解決的問題,但是在我年輕的時候還沒遇到過設計問題。在構造函數中委託調用

我有一個課程,在發生任何事情之前需要經過幾個安裝程序。

但是,在構造此類期間,我在構造函數的參數中有一個可以傳遞的委託,以便用戶可以將其自己的信息添加到該類中。

當這被稱爲但是創建該類的範圍仍然沒有有效的實例,因此發生空異常錯誤。

我該如何設計?我應該將「this」的實例傳遞給該代理嗎?

在這做什麼是一個很好的決定?我有一個「StartServices()」方法,可以方便地將調用發送給委託,但我覺得應該在構造函數中設計明智。

感謝您的建議!

+1

請添加您的代碼,在這麼晚的時候很難將其可視化:) – 2009-12-28 23:02:55

+0

爲什麼您不能僅僅在創建類之後調用類方法來添加附加信息?既然你傳遞了一個委託,你可能知道在創建時應該添加哪些信息。 – vava 2009-12-28 23:08:38

+0

@ bobber205 - 重申您的評論,它遵守普通的可訪問性規則,這意味着它*可以*在適當的環境下訪問私有/受保護/內部等*。 – 2009-12-28 23:30:38

回答

6

這聽起來像你想傳遞一個Action<T>(或類似),這樣在任何一個點的類希望代表,它可以調用theDelegate(this);例如:

var instance = new SomeType(..., obj => { /* extra code invovling obj */ }); 

然後obj將是實例被創建時,它有編譯器生成的方法不需要任何國家/捕獲的好處(除非你需要自己)。

但是!我會謹慎地在內部調用一個委託的構造函數,出於同樣的原因,virtual應該謹慎對待 - 在深層對象模型中,整個類可能不會完全創建在中級構造函數(調用委託或重寫的方法)觸發,提供對不完整狀態的對象的惡意訪問。

+0

代表只能訪問該類上的公共方法。謝謝(你的)信息! – bobber205 2009-12-28 23:20:39

4

考慮使用factory method

public class MyClass 
{ 
    private MyClass() {} 

    public static MyClass Create(delegate d ...) 
    { 
     var instance = new MyClass(); 
     d.(instance); 
     return instance; 
    } 
} 

然後使用它是這樣的:

var o = MyClass.Create(...); 

你也可以去同一個工廠類:

var o = factory.CreateMyClass(...); 
2

基本上,這聽起來像你想要的代碼不應該在構造函數中。構造函數是創建對象的東西。在退出之前,對象不能保證「正常工作」。現在,它可能工作,是的,你可以得到這個指針,但調用代碼會期望它完全構造。所以從設計的角度來看,這不是一個好的做法。只需要在構造函數之後調用另一個方法(如果接口能夠幫助您的多態性,則使用該方法)。

0

這種方法似乎很奇怪,通過代表完成了什麼樣的設置工作?

也許在構造函數的末尾引發一個事件會是一個更標準的方法。

3

我建議不要在構造函數中使用委託。代表可以很容易地訪問其他線程上的數據,導致一些非明顯的副作用。在這種情況下,您應該拆分類創建和類初始化。

使用Factory pattern將幫助您對複雜對象創建乾淨獨立的責任,但沒有對象初始化。我確實考慮將行爲注入構造函數中的反模式。

A問題的解決方案可以通過定義良好的接口將行爲注入(對象)依賴關係。您希望將代表移交給constractur意味着對我的關注和違反Singel責任原則的疏忽。