【问题标题】:How can I unite attachments of generic type event handlers?如何联合泛型类型事件处理程序的附件?
【发布时间】:2019-01-19 15:09:56
【问题描述】:

我有一个动物接口,我有一些实现该接口的类。

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;
}

我有一个类,它有一个事件处理程序,它将指定类型的动物设置为事件 args 的通用属性。

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;
    }
}

【问题讨论】:

    标签: c# generics events event-handling eventhandler


    【解决方案1】:

    解决这个问题的一种方法是创建动物类:

    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。

    对于客户端,将有一个从抽象基类公开的事件。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 2013-10-19
      相关资源
      最近更新 更多