2009-11-18 78 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;