首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事件+适配器模式

事件+适配器模式
EN

Stack Overflow用户
提问于 2011-01-13 11:11:40
回答 3查看 1.4K关注 0票数 3

我在泛型类上有一个适配器模式,它本质上是在类型之间进行适配:

代码语言:javascript
复制
class A<T> { event EventHandler e; }
class Aadapter<T1, T2> : A<T1> { A<T2> a; Aadapter(A<T2> _a) { a = _a; }  }

问题是A包含一个事件。我实际上希望分配给Adapter的所有事件处理程序都落入一个。

如果我可以将a的事件处理程序分配给适配器的事件处理程序,那就太棒了,但这是不可能的?

这里的想法是A几乎真的就是A,但我们需要一种方法来适应它们。由于事件的工作方式,除了手动添加两个事件处理程序,当它们被调用时,它们被“中继”到另一个事件,我无法有效地做到这一点。虽然这并不漂亮,但如果我能有像这样的东西,那会更好

代码语言:javascript
复制
class A<T> { event EventHandler e; }
class Aadapter<T1, T2> : A<T1> { event *e; A<T2> a; Aadapter(A<T2> _a) { a = _a; e = a.e; }  }

在某种意义上,我们有一个指向事件的指针,我们可以将2的事件赋值给它。

我怀疑有任何简单的方法,但也许有人有一些想法让它工作。

(顺便说一句,我意识到这在虚拟事件中是可能的,但如果可能的话,我想避免这种情况)

EN

回答 3

Stack Overflow用户

发布于 2011-01-13 13:09:43

我想这就是你想要的:

代码语言:javascript
复制
    class A<T>
    {
        public virtual event EventHandler e;
    }

    class Aadapter<T1, T2> : A<T1> 
    { 
        A<T2> a; 
        Aadapter(A<T2> _a) { a = _a; } 
        public override event EventHandler  e
        {
            add { a.e += value; }
            remove { a.e -= value; }
        }
    }

或将其链接起来

代码语言:javascript
复制
class A<T>
{
    public event EventHandler e;

    protected void ChainEvent(object sender, EventArgs eventArgs)
    {
        e(sender, eventArgs);
    }
}
class Aadapter<T1, T2> : A<T1> 
{ 
    A<T2> a; 
    Aadapter(A<T2> _a)
    {
        a = _a;
        a.e += ChainEvent;
    }
}
票数 2
EN

Stack Overflow用户

发布于 2011-01-13 11:51:10

为什么订阅和转发事件并不美观?我觉得它很优雅。

这样做与适配器其余部分的实现方式是一致的。

即使你可以使用指针,它也是不一致的,因为你不会想在每种情况下都这样做。

例如,如果您要将一个实现了INotifyPropertyChanged的类改写为一个接口,而该接口没有实现,但却公开了两个属性,比如"TitleChanged“和"MaxLengthChanged”,那么就不会使用指针。您的适配器将公开这两个事件,消费者将进行订阅。您的适配器将订阅PropertyChanged事件,并仅在收到"Title“已修改的通知时引发"TitleChanged”,并仅在收到"MaxLength“已被修改的通知时引发"MaxLengthChanged”。所有其他通知将被忽略。

我喜欢这种方法,因为我发现它简单、一致并且符合模式。

票数 0
EN

Stack Overflow用户

发布于 2011-01-13 13:35:29

示例显示了解决问题的“标准”方法。第一种使用虚拟事件/方法,而第二种使用“双端”转发方案。这两种方法各有优缺点,但如果有一种更简单的方法,而不是随着事件数量的增加而增长,那就更好了。我们想要做的是将这两个事件直接组合成一个事件,而不是间接的,这就是所有这些代码所做的事情。(如果指针在C#中是可能的,那么它们就是这样一种方法)

代码语言:javascript
复制
//#define __virtual
#define __direct

using System;
using System.Collections.Generic;
using System.Text;



namespace VirtualEvents
{



    #if __virtual
    #region
    public class A<T> 
    { 
        public virtual event EventHandler e;

        public virtual void Fire() { e(this, null); }
    }

    public class Aadapter<T1, T2> : A<T1> 
    { 
        A<T2> a;


        public override event EventHandler e
        {
            add { a.e += new EventHandler(value); }
            remove { a.e -= new EventHandler(value); }
        }

        public override void Fire()
        {
            a.Fire();
        }

        public Aadapter(A<T2> _a) 
        { 
            a = _a; 
        } 
    }
    #endregion
    #elif __direct
    #region

    public delegate EventHandler EventHandlerPtr();
        public class eventPtr
        {
            public EventHandler _event;
        }
    public class A<T>
    {


        //internal EventHandler _event;
        public eventPtr _event = new eventPtr();

        public event EventHandler e
        {
            add { _event._event += value; }
            remove { _event._event -= value; }
        }

        public void Fire() { _event._event(this, null); }


    }

    public class Aadapter<T1, T2> : A<T1>
    {
        A<T2> a;

        public Aadapter(A<T2> _a)
        {
            a = _a;
            this._event = a._event;
        }
    }

    #endregion
    #else
    #region 
    public class A<T>
    {
        public event EventHandler e;

        public void Fire() { e(this, null); }
    }

    public class Aadapter<T1, T2> : A<T1>
    {
        A<T2> a;

        public Aadapter(A<T2> _a)
        {
            a = _a;

            a.e += new EventHandler(a_e);
            e += new EventHandler(Aadapter_e);
        }

        void Aadapter_e(object sender, EventArgs e)
        {
            a.e -= new EventHandler(a_e);
            a.Fire();
            a.e += new EventHandler(a_e);
        }

        void a_e(object sender, EventArgs e)
        {       
            this.e -= new EventHandler(Aadapter_e);
            Fire(); 
            this.e += new EventHandler(Aadapter_e);
        }
    }
    #endregion
    #endif


    class Program
    {
        static void Main(string[] args)
        {

            var a = new A<double>();
            var q = new Aadapter<int, double>(a);

            a.e += new EventHandler(a_e);
            q.e += new EventHandler(q_e);


            a.Fire();
            q.Fire();
            ((A<int>)q).Fire();

            Console.ReadKey();
        }

        static void a_e(object sender, EventArgs e)
        {
            Console.WriteLine("From a");
        }

        static void q_e(object sender, EventArgs e)
        {
            Console.WriteLine("From q");
        }

    }
}

(编辑:代码现在包括了一个新的方法,它将事件包装在一个类中,这个类现在允许轻松有效地分配事件,表示“指针”的情况。希望有人能在这些方面做更多的改进。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4676437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档