2009-04-12 12 views
1

次の例はC# in Depth: What you need to master C# 2 and 3から取得されており、jskeetが特定したが間違っているだけで、大きな変更が発生するようです。説明してください:contravarianceは告白された動作を引き起こすようです

delegate void SampleDelegate(string x); 

public void CandidateAction (string x) 
{ 
    Console.WriteLine("Snippet.CandidateAction") 
} 

public class Derived: Snippet 
{ 
    public void CandidateAction (object x) 
    { 
    Console.WriteLine("Derived.CandidateAction") 
    } 
} 
.... 

Derived x = new Derived(); 
SampleDelegate factory = new SampleDelegate (x.CandidateAction); 
factory ("test"); 

をSampleDelegateが文字列ないオブジェクトを受け入れるよう、なぜそれが完全に動作するはずです。私の知る限り、オブジェクトは文字列から派生しません。それは別の方法です。それはC#2.0の下でcontravarianceが許すものです。反対の効果を発揮するようです。

おかげ

答えて

3

概念的には、Derived.CandidateActionの署名は、「私はあなたが私を投げるしたい任意のオブジェクトを扱うことができる。」と言っていますSampleDelegateの契約は「あなたは文字列を処理できる必要があります。メソッドが任意のオブジェクトを処理できるようになったら、確実に文字列を処理できます。したがって、Derived.CandidateActionは、SampleDelegateが必要とするものを満たすことができるため、SampleDelegate変数に割り当てることができます。

私はhttp://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.htmlにこれについての詳細な議論をしました(C#4の観点から)。

1

Contravarianceでは、デリゲートメソッドシグネチャのパラメータの基本型であるパラメータを持つメソッドを使用できます。

デリゲートシグネチャは、どのタイプがメソッドに渡されるかを定義します。メソッド自体には、「特異的」ではないタイプがあります。あなたの例では、文字列が渡されるときにデリゲートが呼び出されます。実際のメソッドでは、オブジェクト型の変数にstring型のインスタンスを保持することが許可されているため、オブジェクトのみが必要です。

これは、あなたが、ほぼすべてのイベントにアタッチすることができ、このようなイベントハンドラを(引数パラメータが渡されている場合でも、ItemCheckedEventArgsような、より具体的である)書くことができるシナリオを扱う場合に最も有用である:

public void GenericHandler(object source, EventArgs args) { 
    //do something generic 
} 
関連する問題