2009-11-18 50 views
0

假設我有代碼段C#:繼承@代表

namespace Test 
{ 
    public delegate void StaticticsDelegate(object sender,EventArgs e); 

    class DynamicDelegates 
    { 

     static void Main() 
     { 
      StaticticsDelegate del = BowlerStatistics; 
      BallThrownEventArgs be = new BallThrownEventArgs(90, 145); 
      del(DynamicDelegates.Main,be); 

      del = BatsmanStatistics; 
      RunsScoredEventArgs re = new RunsScoredEventArgs("Skeet", 55); 
      del(DynamicDelegates.Main, re); 
      Console.ReadLine(); 
     } 


     static void BowlerStatistics(object sender, BallThrownEventArgs e) 
     { 
     Console.WriteLine 
     ("{0} sender is ; Bowler Statistics :speed {1} angle {2}", 
      sender, e.Speed, e.Angle); 
     } 

     static void BatsmanStatistics(object sender, RunsScoredEventArgs e) 
     { 
      Console.WriteLine 
      ("{0} sender is ; Batsman Statistics :name {1} runs {2}", 
      sender, e.PlayerName, e.Runs); 
     } 

    } 

    class BallThrownEventArgs:EventArgs 
    { 
     int angle; 
     int speed; 
     public BallThrownEventArgs(int angle, int speed) 
     { 
      this.angle = angle; 
      this.speed = speed; 
     } 

     public int Angle 
     { 
      get { return angle; } 
     } 

     public int Speed 
     { 
      get { return speed; } 
     } 

    } 

    class RunsScoredEventArgs : EventArgs 
    { 
     string playerName; 
     int runs; 
     public RunsScoredEventArgs(string playerName, int runs) 
     { 
      this.playerName = playerName; 
      this.runs = runs; 
     } 

     public string PlayerName 
     { 
      get { return playerName; } 
     } 

     public int Runs 
     { 
      get { return runs; } 
     } 
    } 

} 

1)由於 「BallThrownEventArgs」 和 「RunsScoredEventsArgs」 從 「EventArgs的」,爲什麼 做了錯誤「沒有重載匹配衍生... 「當我執行」Main()「時生成 。

2)「ContraVariance」和「Covariance」是什麼意思(請給我一個例子來理解)?

3)術語「逆變」和「協方差」僅與代表有關?

+0

約CO /逆變相關問題: Konamiman 2009-11-18 08:00:01

回答

2

問題是你試圖用錯誤的方式。

方差的想法是,如果作爲代表表示將提供,如果你的方法比委託返回更多具體的信息必須返回,那麼你沒事你的方法並不需要具體信息使用該方法構建委託。

根據你的情況,事情倒過來:

public delegate void StatisticsDelegate(object sender, EventArgs e); 

static void BowlerStatistics(object sender, BallThrownEventArgs e) 

BowlerStatistics已經給予一個BallThrownEventArgs,但StatisticsDelegate只保證它會提供一個EventArgs

假設您可以從BowlerStatistics創建StatisticsDelegate:您期望下列代碼做什麼?

StaticticsDelegate del = BowlerStatistics; 
del(null, new EventArgs()); 

BowlerStatistics將不會有任何與球有關的信息。

或者使用現有的代碼,但它移動了一下週圍:

StaticticsDelegate del = BowlerStatistics; // * 
    RunsScoredEventArgs re = new RunsScoredEventArgs("Skeet", 55); 
    del(DynamicDelegates.Main, re); 

    del = BatsmanStatistics; // * 
    BallThrownEventArgs be = new BallThrownEventArgs(90, 145); 
    del(DynamicDelegates.Main,be); 
    Console.ReadLine(); 

這一次你試圖做一個投手統計委託應付擊球手的統計數據,反之亦然!唯一可能無法編譯的行是方法組轉換的(上面標記爲// *) - 所以爲了實現類型安全,它們不會編譯。

協變和逆變是棘手的話題 - 你可能會發現Eric Lippert's series of blog posts有用。在C#4之前,方差僅適用於創建代表;作爲C#4還有接口類型和委託通用方差,讓你寫:

// Covariance 
IEnumerable<string> strings = new List<string>(); 
IEnumerable<object> objects = strings; 

// Contravariance 
Comparer<Shape> areaSorter = (s1, s2) => s1.Area.CompareTo(s2.Area); 
Comparer<Triangle> triangleAreaSorter = areaSorter;