2012-12-13 16 views
11

I私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); 

私は2つの候補方法 のどちらが最も特異的であることがエラーを取得します。しかし、私はMaybe<T>が となると思ったのですが、より多くより具体的にはTかそれとも正しくありませんか?

EDIT

私は明示的に拡張メソッド を呼び出す場合ので、それはcuriouserを取得します。

MessageBus.SubscribeTo(source, bus); 

そして、それが動作し、正しい方法を選びます。それが唯一の第二の方法が適用される今だと...

source.Subscribe<string>(bus); 

+0

あなたはそれを動作させることができます: 'パブリック静的IDisposableをTは( このIObservable 、観察、 MessageBusバス)登録:たぶん' – 2kay

+0

Tはたぶん bradgonesurfing

+3

2kay @ジェネリック制約することはできませんが、の一部ではありません候補の解決プロセスは、動作しませんので、 – SWeko

答えて

9

さて、あなたは型引数を指定することによって、それを修正することができます。あなたが最初に二以上の特定であると考えられる場合は

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

すると、あなたはそれだ:)ので、言うC#の仕様のルールを見つける必要があります:

そうでない場合、コンパイラは、のいずれかを呼び出すことができます不合理な期待ではありませんが、私はそうではありません普通の "より具体的な"変換は、タイプのパラメータと通常のパラメータに当てはまります。だから、

例えば、C#4仕様( "より良い関数メンバ")は、ルールについてのセクション7.5.3.2で:

  • それ以外の場合はM Pは、より具体的なパラメータの型よりを持っている場合M Q、次にM PがM Qより優れている。 [...より少ない/より具体的な詳細についてたくさんの...]

...しかし、型パラメータについての同様のポイントがありません。 (2番目の引数は型引数について述べていますが、それはパラメータ型の中にあります)。

もう1つの方法は、メソッドに異なる名前を付けることです。彼らは微妙に異なる行動をしていますか?もしそうなら、名前をつけてそれを本当に明白にするのはどうですか?あなたは本当に過負荷が呼び出されたことに驚いただけなので、誰かが間違った行動を取ることを望んでいません。予想通り

+1

こんにちはジョン。別の結果を与える拡張メソッドを直接呼び出すことで質問を更新しました。拡張メソッドが専門化できないのに対して、直接呼び出しはなぜですか。これは標準の理解に合っていますか? – bradgonesurfing

+0

この場合、私はコンパイル時に安全ですので直接呼び出しを行います。 – bradgonesurfing

関連する問題