C #: Наследование @ Делегаты - PullRequest
0 голосов
/ 18 ноября 2009

Предположим, у меня есть сегмент кода

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) Термины «контравариантность» и «ковариантность» относятся только к делегатам?

Ответы [ 2 ]

2 голосов
/ 18 ноября 2009

Проблема в том, что вы пытаетесь использовать дисперсию неправильно.

Идея отклонения состоит в том, что если вашему методу не нужна такая конкретная информация, которую, как говорит делегат, он предоставит, и если ваш метод возвращает больше конкретной информации, чем должен вернуть делегат, то вы все в порядке, чтобы построить делегат, используя этот метод.

В вашем случае все наоборот:

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

static void BowlerStatistics(object sender, BallThrownEventArgs e)

BowlerStatistics имеет для получения BallThrownEventArgs, но StatisticsDelegate только гарантирует, что он даст EventArgs.

Предположим, вы можете создать StatisticsDelegate из BowlerStatistics: что вы ожидаете от следующего кода?

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();

На этот раз вы пытаетесь заставить представителя статистики боулера справиться со статистикой игрока с битой и наоборот! Единственные строки, которые не могут быть скомпилированы, - это группы преобразования групп методов (помеченные // * выше), поэтому для обеспечения безопасности типов они не компилируются.

Ковариантность и контравариантность - сложные темы - вы можете найти серию сообщений Эрика Липперта в блоге полезной. До 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;
1 голос
/ 18 ноября 2009

Просто пытаясь помочь здесь, вы смотрели видео Эрика Липперта, где он объясняет некоторый код для Contravariance и Covariance. Вот ссылка на 2 видео, http://msdn.microsoft.com/en-us/vcsharp/ee672314.aspx и http://msdn.microsoft.com/en-us/vcsharp/ee672319.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...