我正在做一個遺留應用程序,因爲繼承有一些缺陷,但我正在努力解決它。在C#winforms中消除繼承「魔術」的最佳方法是什麼?
此刻的WinForms的結構是這樣的:
BaseForm
ListViewForm : BaseForm
ListViewFormReadOnly : ListViewForm
ListViewFormWithDetailForm : ListViewForm
DetailForm : BaseForm
ConcreteForm : ListViewFormWithDetailForm
BaseForm裏面有一個方法叫做sth,像protected virtual void InitializeMyStuff()
這個被覆蓋在繼承的實例中。
例如
public class BaseForm {
public BaseForm() {
//.. do stuff
//.. do other stuff like initialize DB connection or read app.config values and initialize properties..
}
public virtual void InitializeMyStuff() {
throw new NotImplementedException();
}
}
public class ListViewForm : BaseForm {
protected BindingSource GridBindingSource { get; set; }
public ListViewForm {
//do special stuff like adding the grid and some buttons
}
}
public class ConcreteForm : ListViewForm {
public override void InitializeMyStuff() {
GridBindingSource = my_bindingSource;
SomeOtherUsefulProperty = myValue;
Foo = new Bar();
// etc.
}
}
//Usage:
var myForm = new ConcreteForm();
myForm.InitializeMyStuff();
正如你能想象這產生了一些問題,如: - 「我有什麼事情要設定在這一點上的形式合作」 - 「什麼事情可能還沒有被初始化?」 - 「哪些屬性和方法調用仍在使用中」 以及關於該魔法黑盒中可能發生的一些其他有趣想法。
我該如何重構這個,使其更清楚發生了什麼?請記住,這是一個包含約150個或更多具體表單的項目。
我最初的想法是將例如GridBindingSource
這些神奇屬性封裝到一個對象中(例如FormConfiguration
),並使其在BaseForm
中保密。
例如類似的東西
public class BaseForm {
private FormConfigObject _formConfig = new FormConfigObject();
protected override void OnLoad()
{
InitializeMyStuff(_formConfig);
}
protected virtual void InitializeMyStuff(FormConfigObject config)
{}
}
的問題,我這裏是:ListForm的FormConfig對象就必須有例如其他屬性,如GridBindingSource
但我不能只是改變在派生類中籤名的ListFormConfigObject
是不是FormConfigObject
..
有人可以建議可能的解決方案擺脫這種困境?
//編輯:將代碼簡化爲實際發生的事情,並在構造函數違規中擺脫虛擬調用。
這也違反了'CA2214'規則:http://msdn.microsoft.com/en-us/library/ms182331.aspx - 虛擬方法不應該在構造函數中調用。 – BartoszKP
你有什麼好的理由去改變它嗎?起初,我的想法是刪除所有'InitializeMyStuff',一個虛擬調用ctor是一個壞主意,但這是很多工作。 –
這個問題可能是更適合http://codereview.stackexchange.com/ –