Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将事件附加到公共类中的方法?_C#_Design Patterns_Events_Event Handling - Fatal编程技术网

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

C# 如何将事件附加到公共类中的方法?,c#,design-patterns,events,event-handling,C#,Design Patterns,Events,Event Handling,假设我有以下两门课: public class User { public int ID { get; } public string Name { get; set; } public void ChangeName(string newName) { Name = newName; } } public class Mail { p

假设我有以下两门课:

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
会被自动调用

我知道我可以使用事件来处理这个问题,但我想做的是创建第三个静态类来构建这个事件,并在类中说:attach
ChangeName
to
SendUserInfoChangeEmail

我该怎么做

注意:
我不想把任何事件 在两个用户界面中处理或委托 还有电子邮件课程我什么都想要 通过第三个新的
静态类。

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

您可能希望查看INotifyPropertyChanged接口,以了解其他人是如何完成此类操作的


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

您可能希望查看INotifyPropertyChanged接口,以了解其他人是如何完成此类操作的


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

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

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 framework的邮件系统来发送电子邮件,那么mail可以是一个静态类,包含发送各种类型预定义电子邮件的方法(不是最好的设计,但一开始是可行的),包括一个方法SendUserInfoChangeEmail()。您的事件处理程序可以调用它。

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

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

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 framework的邮件系统来发送电子邮件,那么mail可以是一个静态类,包含发送各种类型预定义电子邮件的方法(不是最好的设计,但一开始是可行的),包括一个方法SendUserInfoChangeEmail()。可以由事件处理程序调用。

关于设计模式,请查看设计模式,请查看

  • 为什么除了
    Name
    属性之外,还需要一个
    ChangeUser
    方法,该属性的作用完全相同,只是更简洁而已
  • SendUserInfoChangeEmail
    是什么意思?它的目的是什么?为什么是邮件类?在
    User
    类或类似的类中使用它不是更好吗
  • 为什么是静态三等舱
  • 无论如何,我会将
    User
    类更改为如下内容:

    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));
        }
    }
    
    然后,在任何你喜欢的地方,你的静态类或任何东西,订阅该事件,并在名称更改时发送电子邮件

  • 为什么除了
    Name
    属性之外,还需要一个
    ChangeUser
    方法,该属性的作用完全相同,只是更简洁而已
  • SendUserInfoChangeEmail
    是什么意思?它的目的是什么?为什么是邮件类?在
    User
    类或类似的类中使用它不是更好吗
  • 为什么是静态三等舱
  • 无论如何,我会将
    User
    类更改为如下内容:

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

    然后,在你喜欢的任何地方,在你的静态类或任何东西中,订阅该事件并在名称更改时发送电子邮件。

    我认为你所说的有时被称为事件代理类。当您不希望两个类之间存在硬依赖关系时,它是一个充当中介的类

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

    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();
        }
    }
    
    公共类用户
    {
    公共int ID{get;}
    公共字符串名称{get;set;}
    public void ChangeName(字符串newName)
    {
    Name=newName;
    UserEventProxy.FireUserNameChanged(此);
    }
    }
    公共类UserEventArgs:EventArgs
    {
    公共用户{get;set;}
    }
    /// 
    /// 
    /// 
    公共静态类UserEventProxy
    {
    /// 
    ///指示关联的用户名已更改。
    /// 
    公共静态事件EventHandler用户名已更改;
    /// 
    ///激发UserNameChanged事件。
    /// 
    ///报告名称更改的用户。
    公共静态无效FireUserName已更改(用户)
    {
    EventHandler=UserNameChanged;
    if(处理程序!=null)
    {
    UserEventArgs args=新的UserEventArgs()
    {
    用户=用户
    };
    //取消该活动。
    UserNameChanged(用户,参数);
    }
    }
    }
    公营邮件
    {
    公共邮件()
    {
    UserEventProxy.UserNameChanged+=