2017-08-21 140 views
-1

所以,我在下面的結構寫兩個接口:C# - 接口設置屬性{獲取,設置}另一個接口

public interface IBar 
{ 
    string DoStuff(); 
} 

public interface IFoo 
{ 
    IBar Bar { get; set; } 
} 

在我執行的IFoo,我必須做這樣的事情:

public class FooImpl : IFoo 
{ 
    private BarImpl _barImpl; 

    public IBar Bar 
    { 
     get { return _barImpl } 
     set { _barImpl = (BarImpl) value } 
    } 
} 

然後我會永遠在使用它,除非我管理,我不希望一些隱含的運營商圍繞鑄造的東西。

那麼,有沒有更好的辦法,以繞不投的東西,也許對我實施清潔Property { get; set; }寫?

編輯 只是爲了澄清爲什麼我(認爲)我需要它是這樣的:比方說,我FooImpl我需要的BarImpl具體方法一起工作。但DoStuff(),這是所有IBars共同可能會從另一個地方如fooImpl.Bar.DoStuff()調用。那有意義嗎?

謝謝!

+0

FooImpl *是否需要* BarImpl? –

+0

這是糟糕的設計,你不應該投射到'BarImpl',而應該把它當作'IBar'。如果你不能/不會那麼做,你應該把'Bar'屬性的類型設置爲'BarImpl'來開始。 –

+0

請看我的編輯 –

回答

1

你可以有一個構造函數有這需要IBar類型參數的對象,並從中將鬆耦合添加到它的類外通過BarImpl喜歡:

public class FooImpl : IFoo 
{ 
    private IBar _barImpl; 

    public IBar Bar 
    { 
     get { return _barImpl } 
     set { _barImpl = value; } 
    } 

    public FooImpl(IBar bar) 
    { 
     _barImpl = bar; 
    } 
} 

在這種情況下,你會想使您IBar屬性只讀,以便它不能從外部改變,因此只需添加吸氣劑是這樣的:

public IBar Bar 
{ 
    get { return _barImpl; }  
} 

這樣你FooImpl只知道該接口nd不與執行IBar緊密相關,任何實現都可以從外部傳遞。

現在創造的FooImpl實例時,你將不得不通過BarImpl作爲參數:

BarImpl bar = new BarImpl(); 
var foo = new FooImpl(bar); 

希望它能幫助!

+0

我喜歡這個回答...沒想過,但請看我的編輯。我認爲它不適用 –

+0

上面提出的解決方案可以正常工作你在編輯中要求的內容 –

+0

是的,我的意思是,它會但我不得不以另一種方式施展:當我想使用'BarImpl'的特定方法時在我的'FooImpl'上,我必須施展它......想到這一點,我不認爲有一種方法可以逃脫施法......也許對於泛型的建議,我們可以看看它。 –

1

我覺得你接近接口的錯誤的方式的概念。絕對地,IFoo不應該要求具體實現IBar。在您的IFoo實施中,刪除對BarImpl的任何引用,並將其替換爲IBar

如果由於特殊原因FooImpl只能與BarImpl一起使用,並且沒有其他實現,那麼在您的IoC註冊中,只需設置它即可。如果我不知道您使用的是哪個IoC容器,則無法引導您完成這項工作。如果你根本沒有使用IoC,你當然可以實例化適當類型的IBar

+0

請看我的編輯 –

+1

@JoãoMenighin我讀過你編輯,但很難在不知道你的實際情況下幫助你。如果'IFoo'需要'BarImpl'特定的東西,也許它應該在'IBar'接口中,或者'IBar'過於通用,您需要其他接口來實現其他功能。 – Tipx

2

如何用一個通用的接口?試試這個代碼:

public interface IFoo<T> where T : IBar 
{ 
    T Bar { get; set; } 
} 

public class FooImpl : IFoo<BarImpl> 
{ 
    private BarImpl _barImpl; 

    public BarImpl Bar 
    { 
     get { return _barImpl; } 
     set { _barImpl = value; } 
    } 
} 
0

一種選擇是使用explicit interface implementation

public class FooImpl : IFoo 
{ 
    private BarImpl _barImpl; 

    public BarImpl Bar 
    { 
     get { return _barImpl; } 
     set { _barImpl = value; } 
    } 

    IBar IFoo.Bar 
    { 
     get { return _barImpl; } 
     set { _barImpl = (BarImpl)value; } 
    } 
} 

在這種情況下,任何你與FooImpl類型的對象的工作時間內,Bar屬性將返回一個BarImpl類型,不需要將其轉換爲調用代碼。然而,該課程仍適當地執行IFoo,並將在任何情況下返回IBar參考,並將其用作參考IFoo

此實現變得更清潔,如果你可以改變IFoo.Bar被只讀,而是需要IFoo實施者通過構造函數或其他方式來獲得他們的IBar成員。這允許FooImpl需要BarImpl實現IBar而不需要在IFoo.Bar設置器中投射。