2012-12-13 100 views
11

我有我的MessageBus以下擴展方法:C#專業化

public static class MessageBusMixins 
{ 
    public static IDisposable Subscribe<T>(
     this IObservable<T> observable, 
     MessageBus bus) 
    where T:class 
    { 
     ... 
    } 

    public static IDisposable Subscribe<T>( 
     this IObservable<Maybe<T>> observable, 
     MessageBus bus) 
    { 
     ... 
    } 
} 

它編譯罰款。然而,當我嘗試使用它:

IObservable<Maybe<string>> source = ...; 
MessageBus bus = ...; 

source.Subscribe(bus); 

我得到的錯誤,無論是兩個候選方法 是最特殊的。不過,我認爲Maybe<T>會 是更多具體比T還是那不正確?

編輯

它變得不尋常了,因爲如果我調用擴展方法 明確,那麼:

MessageBus.SubscribeTo(source, bus); 

然後,它的工作原理,並挑選正確的方法。

+0

你可以把它按預期工作:'公共靜態IDisposable的訂閱( 此的IObservable 觀察到, MessageBus總線),其中T:也許' – 2kay

+0

,T不能或許 bradgonesurfing

+3

@ 2kay通用約束不是的一部分候選人解決​​過程中,這樣不會起作用 – SWeko

回答

9

好了,你可以通過指定類型參數修正:

source.Subscribe<string>(bus); 

...因爲這是現在只有第二種方法是適用的。

否則,編譯器可以調用之一:

source.Subscribe<string>(bus); 
source.Subscribe<Maybe<string>>(bus); 

如果你想到的第一比第二更具體的,你必須要找到其中是這麼說的:)這是C#規範的規則不是一個不合理的期望,但我不認爲認爲正常的「更具體」轉換適用於類型參數以及常規參數。

因此,例如,在部分C#4規格( 「更好的函數成員」)的7.5.3.2有一個規則有關:

  • 否則,如果M P有更具體的參數類型比M Q,則M P優於M Q。 [...許多關於更少/更具體的細節...]

...但有關於類型參數沒有類似的觀點。 (關於正常參數的第二個參數討論類型參數,但這屬於參數類型本身。)

另一種替代方法是簡單地給方法不同的名稱。他們有不同的行爲嗎?如果是這樣,爲什麼不通過命名做出真正的明顯?你真的不希望有人因爲他們對所謂的超載感到驚訝而得到錯誤的行爲。

+1

嗨,喬恩。我通過直接調用擴展方法更新了問題,它給出了不同的結果。爲什麼擴展方法無法專門化,而直接調用卻是不可能的。這是否符合你對標準的理解。 – bradgonesurfing

+0

在這種情況下,我會直接調用,因爲編譯時對我來說是安全的。 – bradgonesurfing