代码之家  ›  专栏  ›  技术社区  ›  Amr Elgarhy

如何将事件附加到公共类中的方法?

  •  1
  • Amr Elgarhy  · 技术社区  · 15 年前

    假设我有以下两个班:

    public class User
        {
            public int ID { get; }
    
            public string Name { get; set; }
    
            public void ChangeName(string newName)
            {
                Name = newName;
            }
    
    
        }
    
        public class Mail
        {
            public void SendUserInfoChangeEmail()
            {
                throw new NotImplementedException();
            }
        }
    

    我要做的是:当某人使用该方法编辑用户对象名时 ChangeName 这个 SendUserInfoChangeEmail 自动呼叫。

    我知道我可以使用事件来处理这个问题,但是我想让第三个静态类在其中构建这个事件,并在类中说:附加 转换名 发送用户信息更改电子邮件

    我该怎么做?

    注:
    我不想举办任何活动 在两个用户中处理或委托 还有电邮课,我什么都要 通过第三个新的 静态类。

    6 回复  |  直到 15 年前
        1
  •  2
  •   Sruly    15 年前

    您可以在用户类上创建一个事件,并在第三个类中订阅它。

    您可能需要查看inotifyPropertyChanged接口,以了解类似的事情是如何由其他人完成的。

    http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(VS.96).aspx

        2
  •  1
  •   Rob Cooke    15 年前

    我想你所说的有时候叫做事件代理类。它是一个类,当您不想在两个类之间有一个硬依赖关系时,它充当中介。

    一般来说,我尽量避免在可以获得对触发对象的引用时使用它,但是有些合法的场景中,事件的使用者可能不知道可能触发它的所有实例。例如,我以前使用它的地方是,当数据有多个视图并且数据不在可以直接引用的单个域对象中时,提供全局数据刷新事件。

    public class User
    {
        public int ID { get; }
    
        public string Name { get; set; }
    
        public void ChangeName(string newName)
        {
            Name = newName;
            UserEventProxy.FireUserNameChanged(this);
        }
    }
    
    public class UserEventArgs : EventArgs
    {
        public User User{get; set;}
    }
    
    /// <summary>
    /// 
    /// </summary>
    public static class UserEventProxy
    {
        /// <summary>
        /// Indicates that the associated user's name has changed.
        /// </summary>
        public static event EventHandler<UserEventArgs> UserNameChanged;
    
        /// <summary>
        /// Fires the UserNameChanged event.
        /// </summary>
        /// <param name="user">The user reporting the name change.</param>
        public static void FireUserNameChanged(User user)
        {
            EventHandler<UserEventArgs> handler = UserNameChanged;
            if (handler != null)
            {
                UserEventArgs args = new UserEventArgs()
                {
                    User = user
                };
    
                //Fire the event.
                UserNameChanged(user, args);
            }
        }
    }
    
    
    public class Mail
    {
        public Mail()
        {
            UserEventProxy.UserNameChanged += new EventHandler<UserEventArgs>(UserEventProxy_UserNameChanged);
        }
    
        private void UserEventProxy_UserNameChanged(object sender, UserEventArgs e)
        {
            User user = e.User;
    
            //
            //Presumably do something with the User instance or pass it to 
            //the SendUserInfoChangedEmail method. to do something there.
            //
    
            SendUserInfoChangeEmail();
        }
    
    
        public void SendUserInfoChangeEmail()
        {
            throw new NotImplementedException();
        }
    }
    
        3
  •  1
  •   Jordão    15 年前

    你想要的模式似乎是 Mediator . 这个简单的例子给了你一个想法:

    public class User {
      public event EventHandler NameChanged = delegate { };
      public int ID { get; }
      public string Name { get; private set; }
      public void ChangeName(string newName) {
        if (newName != Name) {
          NameChanged(this, EventArgs.Empty);
        }
        Name = newName;
      }
    }
    
    public class UserMediator {
      User _user;
      EventHandler _eh;
      public UserMediator(User user, Action onNameChanged) {
        _user = user;
        _eh = (src, args) => onNameChanged();
        _user.NameChanged += _eh;
      }
      public void Detach() {
        _user.NameChanged -= _eh;
      }
    }
    

    其他地方:

    var user = new User();
    var mail = new Mail();
    new UserMediator(user, mail.SendUserInfoChangeEmail);
    
        4
  •  0
  •   siride    15 年前

    您的用户类需要有一个事件,该事件是通过用户名更改触发的。无论哪个对象跟踪用户,都需要有一个订阅用户名更改事件的方法,并且可以创建一个新的邮件对象并发送必要的电子邮件。

    要在用户类中创建事件,请执行以下操作:

    public class User {
        public event EventHandler UserNameChanged;
    
        private string m_Name;
        public string Name {
            get { return m_Name; }
            set {
                if(m_Name != value) {
                    m_Name = value;
                    // assuming single-threaded application
                    if(UserNameChanged != null)
                        UserNameChanged(this, EventArgs.Empty);
                }
            }
        }
    
        // everything else is the same...
    }
    

    在管理代码中,您将拥有一个处理事件的方法:

    private void Handle_UserNameChanged(object sender, EventArgs e) {
        User user = (User)sender;
        // create the mail object and send it        
    }
    

    我认为你现在的邮件课程不会奏效。如果邮件是用来表示邮件消息的,那么它应该提供设置和发送邮件消息所需的所有方法和属性。但是,如果您只需要使用.NET框架的邮件系统发送电子邮件,那么mail可以是一个静态类,其中包含发送各种类型的预定义电子邮件的方法(不是最佳设计,但可以作为开始使用),包括sendUserInfoChangeMail()方法。可以由事件处理程序调用。

        5
  •  0
  •   Victor Hurdugaci    15 年前

    在设计模式方面,请看 Observer Pattern

        6
  •  0
  •   Svish    15 年前
    1. 你为什么想要 ChangeUser 方法除了 Name 完全相同用途的财产更干净?
    2. 什么? SendUserInfoChangeEmail 意思是?它的目的是什么?为什么在邮件类中?把它放在里面不是更好吗 User 等级还是类似的?
    3. 为什么是静态的三等舱?

    无论如何,我会改变 用户 像这样的类:

    public class User : INotifyPropertyChanged
    {
        public int ID { get; }
    
        private string name;
        public string Name
        {
            get { return name; }
            set 
            {
                if(value != name)
                {
                    name = value; 
                    NotifyPropertyChanged("Name");
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged(String name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
    

    然后,在任何你喜欢的地方,你的静态类或者其他什么,订阅这个事件,并在名称改变时发送电子邮件。

    推荐文章