【问题标题】:C# constructor eventC# 构造函数事件
【发布时间】:2011-11-23 14:34:46
【问题描述】:

我创建了一个类,当我通过表单创建一个员工对象时,我想给一个消息;

这是我的班级、活动和代表

public delegate void ctorDel(); 

class Employee
{
    private int empID;
    private string empName;

    public event ctorDel myEvent;

    public Employee(int empID,string empName)
    {
        this.empID = empID;
        this.empName = empName;

        **if (myEvent != null)
        {
            myEvent();
        }**
    }

形式上

  int id = Convert.ToInt16(textBox1.Text);
            string name = textBox2.Text;

            Employee emp = new Employee(id, name);
            emp.myEvent += new ctorDel(showMessage);

和功能

 public void showMessage()
        {
            MessageBox.Show("An employee is created");
        }

【问题讨论】:

  • 那你的问题是什么?你哪里有问题?
  • myEvent 永远不会被触发,因为它没有在任何地方设置。
  • 没有人可以附加到事件中,所以这没有意义。

标签: c# events


【解决方案1】:

你想要完成什么?您尝试的原因不起作用是因为您在 ctor 之后附加了您的代表。一旦您调用了“新员工”,该事件早就被解雇了。

如果你真的需要这样的事件,创建一个工厂类:

public delegate void EmpCreated();
public EmployeeFactory {
  public event EmpCreated myEvent;
  public Employee Create(int empId, string empName){
    var result = new Employee(empId, empName);
    if(myEvent != null) myEvent();
    return result;
  }
}

在工厂类上订阅事件,您将获得该事件。

【讨论】:

  • 我可以在员工构造函数中这样做吗?
【解决方案2】:

您在构造函数已经运行之后附加事件。

【讨论】:

    【解决方案3】:

    在构造函数中引发实例事件是没有意义的,因为由于实例的初始化还没有完成,所以不能有任何处理程序附加到事件......

    但是,您可以创建一个静态事件:

    public static event ctorDel myEvent;
    
    ...
    
    Employee.myEvent += new ctorDel(showMessage);
    

    (但不要在每次创建Employee 时都订阅该事件,否则处理程序将被调用多次...)

    【讨论】:

      【解决方案4】:

      解决方案

      这是解决问题的通用方法

      public class EventFactory
      {
          public U Create<U, V>(V constructorArgs)
          {
              var instance = (U)Activator.CreateInstance(typeof(U), constructorArgs);
              OnCreated?.Invoke();
              return instance;
          }
      
          public delegate void CreatedEventHandler();
          public event CreatedEventHandler OnCreated;
      }
      

      你可以这样做

      var ef = new EventFactory();
      ef.OnCreated += myEventHandler; 
      var instance = ef.Create<Employee>(employeeArgs);
      

      .. 更进一步

      当您需要传递事件参数或构造函数无参数时,可以调整我的代码以提供更大的灵活性。我还没有测试过它,但它应该看起来像

      public class EventFactory<T>
      {
          public U Create<U, V>(V constructorArgs, T eventArgs)
          {
              var instance = (U)Activator.CreateInstance(typeof(U), constructorArgs);
              OnCreated?.Invoke(eventArgs);
              return instance;
          }
      
          public U Create<U>(T eventArgs)
          {
              return Create<U, object>(null, eventArgs);
          }
      
          public delegate void CreatedEventHandler(T args);
          public event CreatedEventHandler OnCreated;
      }
      
      public class EventFactory
      {
          public U Create<U, V>(V constructorArgs)
          {
              var instance = (U)Activator.CreateInstance(typeof(U), constructorArgs);
              OnCreated?.Invoke();
              return instance;
          }
      
          public U Create<U>() where U : new()
          {
              var instance = new U();
              OnCreated?.Invoke();
              return instance;
          }
      
          public delegate void CreatedEventHandler();
          public event CreatedEventHandler OnCreated;
      }
      

      【讨论】:

        【解决方案5】:

        创建Employee时可以传递handler:

        private Employee(ctorDel construcEvent)
        {
            if (construcEvent != null)
                this.myEvent += construcEvent;
        }
        
        public Employee(int empID,string empName, ctorDel construcEvent)
            : this(construcEvent)
        {
            this.empID = empID;
            this.empName = empName;
        
            if (myEvent != null)
            {
                myEvent();
            }
        }
        

        然后:

        Employee emp = new Employee(id, name, new ctorDel(showMessage));
        

        【讨论】:

          【解决方案6】:

          当您订阅此事件时,实例已经构建完毕。 我建议使用工厂模式来隐藏构造函数。

          class EmployeeFactory
          {
               public Employee Create(int id, string name)
               {
                   Employee instance = new Employee(id, name);
          
                   var handler = EmployeeCreated;
                   if (handler != null)
                   {
                        EmployeeEventArgs e = new EmployeeEventArgs(instance);
                        handler(e);    
                   }
          
                   return instance;
               }
          
               public event EventHandler<EmployeeEventArgs>  EmployeeCreated;
          }
          

          事件订阅:

            factory.EmployeeCreated += MyHandler;
          

          实例构造:

            var emp = factory.Create(id, name);  
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-13
            • 1970-01-01
            • 1970-01-01
            • 2023-03-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多