[英]Type constraints on constructor for factory method
我發現我的設計是錯誤的,並詢問您如何解決我的問題。
所以我的情況:
我正在編寫工廠方法,對於類,女巫是從我的特殊基類派生的。 所以我寫了
public T MyFactory<T>() where T:MyBaseClass
但是,我工廠方法的主要工作是獲取一些特殊參數並將其傳遞給新對象的構造函數。 MyBaseClass
具有以下構造函數:
public MyBaseClass(MySpecParam param){...}
但是,不能保證從MyBaseClass
派生的T
類型具有此類構造函數。
我看到的唯一解決方案是向MyBaseClass
添加new()
約束和虛擬Init
方法,以便工廠可以安全地創建類型為T
的新對象,然后使用MySpecParam
對象對其進行MySpecParam
。
但是, MyBaseClass
具有這樣的設計,因此,如果不使用MySpecParam
它,將完全無法使用。 用戶可以使用MyBaseClass
參數構造函數創建MyBaseClass
並獲得完全無效(未初始化)的對象。 我覺得不好
無法添加new(MySpecParam)
約束。
我該如何設計對象,構造函數和工廠方法?
如果每個類只有一個公共構造函數,則可以通過反射找到它,確定它需要使用哪些參數,並在調用構造函數時提供適當的值(仍然通過反射)。
否則,我假設您有一組有限的構造函數簽名。 在這種情況下,您將需要某種方法來確定要調用的構造函數。 該決定可以部分地基於類型自變量T
的身份。
編輯
如果您出於評論中概述的原因不願意使用反射,那么答案或多或少是“不,您不能那樣做”。 Michael Yoon建議使用一個IoC框架,該框架當然使用反射,並且也會遇到運行時錯誤。 根據我的經驗(使用Castle Windsor),性能從來都不是問題,並且由於配置錯誤而導致的運行時錯誤幾乎在開發周期中立即被發現。
另一個想法; 這可能沒有幫助,但可能值得考慮。 您可以使用Func<T>
創建實例,甚至可以對不同類型的Func<T, TOut>
, Func<T1, T2, TOut>
等類型的工廠方法進行重載,在其中調用
var obj = FactoryMethod<SomeType>(() => new SomeType(23));
或者,考慮抽象工廠模式 。
聽起來像是IoC容器的問題。 如果您的工廠使用了諸如StructureMap或Unity之類的容器,則不再需要擔心構造函數問題。 工廠將要求StructureMap(例如)解析MyBaseClass,然后將使用貪婪的構造函數返回MyBaseClass的實例,並遞歸地構建其所有依賴項,依此類推。
構造函數不能繼承,也不能在接口上使用。 這意味着每個類的構造函數僅特定於該類。 這也意味着子類可以由不具有與您的模式匹配的構造函數的基類組成。 如果您想以一種標准的方式配置對象,我認為與您的想法類似,在您的基類上使用abstract Init(foo, bar, baz)
是最好的解決方案。 您也可以實現內部邏輯,如果在初始化對象之前訪問了對象,則拋出該邏輯,但是不幸的是,您將無法在編譯時強制執行該邏輯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.