Как я могу объединить вложения обработчиков событий универсального типа? - PullRequest
0 голосов
/ 19 января 2019

У меня есть интерфейс для животного, и у меня есть некоторые классы, которые реализуют интерфейс.

public interface IAnimal
{
    int LegCount { get; }
}

public class Dog : IAnimal
{
    public int LegCount { get { return 4; } }
}

public class Octopus : IAnimal
{
    public int LegCount { get { return 8; } }
}

У меня есть универсальный класс EventArgs, в котором есть экземпляр животного указанного типа.

public class AnimalRequiredEventArgs<TAnimal> : EventArgs
    where TAnimal : class, IAnimal
{
    public TAnimal Animal { get; set; }
}

У меня есть класс, в котором есть события, для которых требуется экземпляр животного указанного типа.

public class MyClass
{
    public event EventHandler<AnimalRequiredEventArgs<Dog>> DogRequired;
    public event EventHandler<AnimalRequiredEventArgs<Octopus>> OctopusRequired;
}

У меня есть класс, в котором есть обработчик событий, который устанавливает животное изуказанный тип для универсального свойства аргументов события.

public class AnimalsManager
{
    private readonly IList<IAnimal> _animals =
        new List<IAnimal>{new Dog(), new Octopus()};

    public void OnAnimalRequired<TAnimal>(object sender, AnimalRequiredEventArgs<TAnimal> e)
        where TAnimal : class, IAnimal
    {
        e.Animal = _animals.OfType<TAnimal>().FirstOrDefault();
    }
}

Как объединить вложения обработчиков событий универсального типа, как показано ниже?

public class Program
{
    public static void Main()
    {
        var manager = new AnimalsManager();
        var mine = new MyClass();

        // How can I unite these event handler attachments?
        mine.DogRequired += manager.OnAnimalRequired;
        mine.OctopusRequired += manager.OnAnimalRequired;
    }
}

1 Ответ

0 голосов
/ 19 января 2019

Один из способов решить эту проблему - создать класс животных:

public interface IAnimal
{
    int LegCount { get; }
}

public abstract class Animal: IAnimal
{
     public virtual int LegCount {get{return 4;}}   

     public event EventHandler<AnimalRequiredEventArgs<Animal>> AnimalRequired;

     protected virtual void OnAnimalRequired(AnimalRequiredEventArgs e)
        {
            // Make a temporary copy of the event to avoid possibility of
            // a race condition if the last subscriber unsubscribes
            // immediately after the null check and before the event is raised.
            EventHandler<AnimalRequiredEventArgs<Animal>> handler = AnimalRequired;
            if (handler != null)
            {
                handler(this, e);
            }
        }
}

public class Dog : Animal
{
    public override int LegCount { get { return 4; } }
}

public class Octopus : IAnimal
{
    public override int LegCount { get { return 8; } }
}

Затем вы можете переопределить OnAnimalRequired в каждом производном классе, если хотите.

Для клиентов будет одно событие из абстрактного базового класса.

Надеюсь, это поможет.

...