2012-11-24 51 views
0

如何對構造函數參數進行約束?
這是一個很好的做法嗎?如何在接口中對構造函數參數進行約束?

我有一個接口,我會要求記錄器組件(由統一注入)。
如何強制執行所有派生類將Logger組件(ILogger)作爲參數?

我找不到任何合適的解決方案。

我發現的唯一解決方法是在接口中放置方法Initialize (<parameters>)。這是一種醜陋的做法,需要特殊處理。

有沒有解決這些問題的設計模式?

+3

你不能在C#中使用接口的構造函數施加約束[見這裏](http://stackoverflow.com/questions/619856/interface-defining-a-constructor-signature)。 – Candide

+0

它不像你看起來有一個'Initialize'方法那麼醜,因爲它接受這些組件所需要的。無論如何,這是解決這個問題的標準方法。 – Servy

回答

3

您不需要約束來強制派生類具有記錄器組件。只需定義基類構造函數即可獲得一個ILogger。

public class Foo 
{ 
    public Foo (ILogger logger) { /* some implementation here */ } 
} 

public class Bar : Foo 
{ 
    public Bar(ILogger logger) 
     : base(logger) 
    { 
     // some implementation here 
    } 
} 

因爲Bar派生自Foo,所以它被迫使用帶有記錄器的構造函數。您還可以創建Foo抽象,這將強制用戶創建派生類的實例,而不是Foo本身。

當你需要定義一個接口時,不要只考慮一個C#接口。抽象類適用於這種情況。通常將抽象類看作接口(而不是C#接口)。你所要求的不能用C#接口完成,因爲它們定義了契約而不是實現。

0

爲什麼你會想要強迫這樣的事情?

專注於什麼是真正的契約(由接口定義),而不是像記錄這樣不重要的事情。應該以某種方式定義合同,即在不失去執行核心功能的情況下不能移除任何方法/屬性。

例如,如果你有一個接口:

interface IAdder 
{ 
    double Add(double first, double second); 
} 

增加是核心功能。你可以有第三個參數ILogger,但沒有它你仍然可以添加。日誌記錄是實現細節,它不應該成爲合作的一部分。

相關問題