2014-01-11 69 views
0

拿這個代碼,例如:爲什麼基礎構造函數在靜態上下文中?如何應對?

public class DisposeMe : IDisposable 
{ 
    public void Dispose() 
    { 
     Console.WriteLine("I'm disposed!"); 
    } 
} 

public class Base 
{ 
    private readonly Object _object; 

    public Base(Object obj) 
    { 
     _object = obj; 
    } 
} 

public class Derived : Base, IDisposable 
{ 
    public Derived() 
     : base(new DisposeMe()) 
    { 
    } 

    public void Dispose() 
    { 
     // Should dispose the object allocated in the constructor. 
    } 
} 

我有這種代碼在實際的程序。

我實際上做的是在Derived構造更換new DisposeMe(),成會造成&回報,但也將其保存在過程中的場的方法,這樣我就可以在Derived.Dispose處置它。

但是我不能,因爲某些原因(超出我),base訪問的構造函數是靜態的。爲什麼?我怎樣才能解決它?

P.S.我知道我可以將Base更改爲IDisposable,並讓它檢查每次處理對象時是否輸入對象是IDisposable。我對不是感興趣。這很麻煩,效率低下,最重要的是分配對象的人應該是負責處理對象的人(否則我會在處理其他地方使用的對象的腳中拍攝自己)。

+1

你會在哪裏把那個工廠方法(這應該創建一個'IDisposable'的)?你能提供一些示範代碼來證明你的意圖嗎?請注意,當您調用Derived構造函數時,您不能使用Derived的*實例方法,因爲您的實例仍在被構造。 –

+0

@MattiasBuelens哦,我現在看到了問題。那麼解決方案可能是什麼?我必須有一個參考來處置。我需要改變我的設計嗎?如果是這樣的東西像什麼? – MasterMastic

+0

_分配對象的人應該是一個負責任的人......確實。它不應該是Base存儲它的責任。你根本不應該有這個問題。認爲這是一個問題:你的基本設計是有缺陷的。 \ –

回答

4

你可以添加受保護的只讀屬性爲Base所以你可以從Derived.Dispose訪問它。

public class DisposeMe : IDisposable 
{ 
    public void Dispose() 
    { 
     Console.WriteLine("I'm disposed!"); 
    } 
} 

public class Base 
{ 
    private readonly Object _object; 
    protected Object _Object { get { return _object; } } 

    public Base(Object obj) 
    { 
     _object = obj; 
    } 
} 

public class Derived : Base, IDisposable 
{ 
    public Derived() 
     : base(new DisposeMe()) 
    { 
    } 

    public void Dispose() 
    { 
     (_Object as IDisposable).Dispose(); 
    } 
} 
+0

很害怕這麼做(當談到OOP時我非常隱祕),但其他選擇是保存同一個參考兩次,一個用於處理,另一個用於處理。你贏了命運; _;謝謝你欣快! – MasterMastic

+1

@Ken我不認爲在類中暴露只讀數據會有什麼錯誤。當你可以改變它們時,問題就開始了。 – Euphoric

+0

哦,我的意思是把我拉回來只是讓它受到保護。 @Steve在實際案例中保證是'IDisposable',儘管我在實際項目中檢查了它爲null。謝謝你們倆。 – MasterMastic

2

我認爲最簡單的辦法就是讓廠家爲Derived類:

public static Derived CreateDerived() 
{ 
    DisposeMe d = new DisposeMe(); 
    return new Derived(d); 
} 

private DisposeMe _d; 
private Derived(DisposeMe d) : base (d) 
{ 
    _d = d; 
} 

,然後你的Dispose方法:

public void Dispose() 
{ 
    _d.Dispose(); 
} 
+0

如果構造函數拋出一個異常,您將泄漏'new DisposeMe'。我認爲最好做一些像'Derived result = null;嘗試{result = new DisposeMe(d); } finally {if(result == null)d.Dispose();} return result;';太糟糕了,沒有更好的模式。 – supercat

0
public class Derived<T> : Base, IDisposable where T : IDisposable, new() 
{ 
    public Derived() 
     : base(new T()) 
    { 
    } 

    public void Dispose() 
    { 
     var obj = base._object as IDisposable; 
     if (obj != null) 
      obj.Dispose(); 
    } 
} 
+0

'_object'對'Derived'不可見。這是'私人'。被接受的答案解決了這個問題,但是謝謝。 – MasterMastic

相關問題