2011-11-23 74 views
2

考慮類似的方法:任何方法返回類型包含一個接口的方法是通用的方法嗎?

IEnumerable<IFoo> DoSomethingRequiringIFooInterface(IEnumerable<IFoo> foos) 

其中,該方法使用的IFoo接口(也許是篩選或排序),但它沒有創造實現IFoo的新對象。

豈不總是是更明智的方法一般這樣的:

IEnumerable<TFoo> DoSomethingRequiringIFooInterface<TFoo>(IEnumerable<TFoo> foos) 
    where TFoo : IFoo 

,以便客戶端可以保存類型?還是有一些缺點(或某些情況下),你不會要做到這一點?

謝謝!

回答

4

你不希望這樣做,如果返回值可以是不同類型實現的IFoo比正在傳遞的對象的對象。通用版本是合適的,如果所有返回需要的元素至少有相同的因此,如果您的函數在提供SpecialFoo時總是返回SpecialFoo,那麼泛型方法更適合,因爲它的約束更加緊密。

+0

這是不正確的答案是誰在使用這種方法的人總是可以做:DoSomethingRequiringIFooInterface (...);所以通用的metod可以和非泛型相同,但是如果他願意的話,用戶可以選擇放置更多的約束。 – watbywbarif

+0

@watbywbarif,不,通用方法的契約是說'如果你給我一些類型爲T的對象,我會提供一些類型爲T的對象'。如果調用方法,則表示方法_has_返回從SpecialFoo派生的類型或類型的對象。將此與非泛型情況比較,用戶可以提供SpecialFoo實例並返回WrapperFoo實例(因爲它們實現了IFoo)。有些情況下您可能想要執行後者(例如使用裝飾器模式添加功能,以實現一個接口類) –

+0

我不明白這是如何改變的事情,因爲他說他不是在創建新的對象。裝飾模式涉及創建新的對象。 – watbywbarif

-1

這有當您嘗試使用它與兩個不同的IFoo對象不利的一面。像:

DoSomethingRequiringIFooInterface({ new AFoo(), new BFoo() }); 

使用第一個版本,這將工作。使用第二個它不會。

+1

第二個爲什麼不工作?如果您傳入的集合是'IEnumerable ',則兩個版本都會返回'IEnumerable '。 – svick

+0

我試過了,它和兩者都可以正常工作。我必須將語法改爲'DoSomethingRequiringIFooInterface(new IFoo [] {new AFoo(),new BFoo()});' –

5

一個可能的缺點是,如果你想重載的方法:

void F(IFoo x) {} 
void F(IBar x) {} 

工作正常。但

void F<T>(T x) where T : IFoo {} 
void F<T>(T x) where T : IBar {} 

不能編譯,因爲這兩種方法現在具有相同的簽名。

+0

+1,非常有趣......沒有想到這一點。 –

0

我寧願通用的方法,因爲你總是可以IFoo的指定方法,並有相同的結果與非泛型方法:

DoSomethingRequiringIFooInterface<IFoo>(...); 

,你也給更好的類型安全選項,用戶baecause他能做到 (如果Foo1:的IFoo):

DoSomethingRequiringIFooInterface<Foo1>(...); 

,準確地知道他越來越IEnumerable<Foo1>.

因此,這意味着該泛型方法更好,因爲給用戶更多的選擇,除了需要編寫更多的文本之外,沒有可用性缺點。

2

一些缺點可能是可能的,如果你正在使用反射來改變或分析代碼,比你必須有更復雜的代碼做,這是因爲複雜的代碼,你嚼用反射較大。

相關問題