回答
編輯:請注意,此答案是在編輯完全更改問題之前給出的。正因爲如此,它現在提到的東西只是在最初陳述的問題中出現。我請你原諒所有的「懸掛指針」。 :-)
簡短的回答:
隨着你發佈的代碼,我沒有看到一個替代鑄造IFoo<T>
。如果你不這樣做,編譯器會發出警告(至少在我的機器上)。
更復雜的答案:
請問您的代碼實際上必須要這樣呢?更具體地說,你是否首先需要演員陣容?
我以爲你會打電話給你的工廠方法或多或少是這樣的:
var stringFoo = FooFactory.CreateFoo<string>();
您必須提供(在這種情況下string
)模板參數明確,因爲它不能從任何方法論證得出(在這種情況下,因爲實際上根本沒有)。顯然,工廠方法將返回一個IFoo<string>
。
現在,因爲你必須明確指定在運行時的類型,你也可以同樣寫:
var stringFoo = StringFoo.Create();
,因此具有內StringFoo
工廠方法,這樣,無條件地做明顯:
public class StringFoo : IFoo<string>
{
...
public static StringFoo Create() // or alternatively, return an IFoo<string>
{
return new StringFoo();
}
}
通過應用這種模式對其他IFoo<T>
實現過,這將節省您的if
鏈或內部FooFactory.CreateFoo<T>
switch
塊,使你的代碼更容易,並擺脫必要投(你關心)。
不要誤解我的意思,我知道支持多個對象類型的工廠方法在某些情況下是有用;但在你的情況下它似乎會造成比它的價值更大的麻煩。
P.S:您可能會發現一些IoC容器有趣的一個方面。它們通常需要進行配置,這包括註冊抽象接口的具體類型(即實現類)的過程;例如(這裏使用Autofac):
var builder = new ContainerBuilder();
builder.RegisterType<StringFoo>().As<IFoo<string>>();
再後來,可以請求一個抽象類型的對象實例:
using (var container = builder.Build())
{
var stringFoo = container.Resolve<IFoo<string>>();
...
}
的Resolve
方法是最有趣的部分。您提供一個抽象類型,並使用註冊類型,它將返回一個StringFoo
類型的具體對象。仔細研究一下,如果它聽起來對你來說不夠過分! :-)
你能描述一下你用這個機制解決的問題嗎?最有可能有更清晰的方法來處理它。
編輯
是的,在代碼味道。您已將任何類型的空間都打開,除非您將其限制回單一類型,並生成運行時異常。爲什麼在這種情況下有一個類型參數?
不,我不是。我不明白提供通用接口的抽象工廠的用處,但最終只會創建一個具體的具體類型。你所描述的是解決你尚未描述的問題。告訴我們這個問題是什麼,而不是你如何解決它的先入爲主的想法,我們將會更好地幫助你。 – 2010-04-12 17:37:50
真空中的技術經常會導致尋找問題的解決方案。在沒有定義這種機制正在處理的情況下,你沒有任何標準可以作出價值判斷。如果您的問題更多地是爲了確定這種方法是否是針對某些問題的可行解決方案,那就不同了。我個人看不到通用工廠的用途,它不是通用的,並且在使用時會導致運行時異常。這就像製造一輛不會開始的汽車,除非你要去超市。 – 2010-04-12 18:41:16
你可以嘗試這樣的事情......
public static class FooFactory
{
private static readonly Dictionary<Type, Type> FooTypesLookup;
static FooFactory()
{
FooTypesLookup = (from type in typeof(FooFactory).Assembly.GetExportedTypes()
let fooInterface =
type.GetInterfaces().FirstOrDefault(
x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IFoo<>))
where fooInterface != null
let firstTypeArgument = fooInterface.GetGenericArguments().First()
select new { Type = type, TypeArgument = firstTypeArgument })
.ToDictionary(x => x.TypeArgument, x => x.Type);
}
public static IFoo<T> CreateFoo<T>()
{
var genericArgumentType = typeof(T);
Type closedFooType;
return FooTypesLookup.TryGetValue(genericArgumentType, out closedFooType)
? (IFoo<T>) Activator.CreateInstance(closedFooType)
: null;
}
}
或者更好的是,介紹自己喜歡的IoC容器(溫莎,結構圖等),以及登記,在那裏實現IFoo的所有類型和然後在需要時解析它們以取代Activator.CreateInstance調用。
我的目標是不使用Activator.CreateInstance()。 – Merritt 2010-04-12 18:29:18
- 1. 什麼是衆所周知的模型示例?
- 2. Django的IF衆所周知聲明
- 3. 有沒有一個衆所周知的分類器庫?
- 4. 專營仿函數時,模板類is_convertible到一個衆所周知的類型
- 5. 是否有一個衆所周知的設計模式允許在異步調用之後註冊回調?
- 6. 什麼是衆所周知的Webkit特定的僞元素?
- 7. 是否有乾燥JSON任何衆所周知的方法
- 8. 本地主機的所有衆所周知的別名?
- 9. 沒有解決方案的衆所周知的idMappedPortTCP問題?
- 10. 是否有一個衆所周知的算法填入網格給定的一組點?
- 11. 如何更正衆所周知的二進制格式的字節順序?
- 12. 這個簡單的Haskell函數是否已經有一個衆所周知的名字?
- 13. 的Python:IF衆所周知聲明多次或
- 14. 衆所周知符號不與職能的工作
- 15. 取消註冊RemotingConfiguration取消註冊衆所周知的類型
- 16. Nginx重定向。衆所周知的端點
- 17. 無需使用衆所周知的函數進行插值
- 18. 如何使用QTcpServer偵聽衆所周知的TCP端口
- 19. 使用衆所周知的加密算法有什麼好處?
- 20. 什麼是衆所周知的方法移動MVP中的圖層周圍的數據
- 21. 爲什麼衆所周知的粘腳註腳本是這樣的?
- 22. python:是否有一個衆所周知的函數來標準化數據的JSON表示?
- 23. 這是一個已知的模式?
- 24. 有沒有一種衆所周知的方式來實現分頁與多個RSS源?
- 25. 用戶可自定義表格中衆所周知的行的最佳方法?
- 26. 在Windows註冊表中配置一個衆所周知的可執行文件的調試器進程
- 27. 從iOS上的圖像中解析出一個衆所周知格式的字符串的方法是什麼?(爲此專門創建了一些庫)?
- 28. LINQ到實體獲取過程中的新衆所周知聲明
- 29. 如何在WKT(衆所周知的文字)格式中插入帶孔的多邊形到Postgis表格中?
- 30. 在API中使用自定義接口或衆所周知的標準接口會更好嗎?
我會在'CreateFoo()'方法中使用開關而不是if鏈。 –
ANeves
2010-04-12 17:08:57