C#触发器事件

本文关键字:事件 触发器 | 更新日期: 2023-09-27 17:58:36

我使用C#,我想从类中触发一个事件:

因此,如果一个类的Price属性发生了更改,则应该触发一个事件onPriceChanged(类外)。然而,我得到了一个错误:

名称"onPriceChanged"在当前上下文中不存在

我该怎么解决这个问题?(我想我可以通过构造函数将事件处理程序传递给类…但如果可能的话,我宁愿不将事件处理函数传递给类)

这是我的代码:

using System;
public delegate void delEventHandler();
class clsItem
{
    //private static event delEventHandler _show;
    private delEventHandler _show;
    private int _price;
    public clsItem()  //Konstruktor
    {
        _show += new delEventHandler(Program.onPriceChanged);  //  error here :  The name 'onPriceChanged' does not exist in the current context
    }
    public int Price
    {
        set
        {
            _price = value;
            _show.Invoke();  //trigger Event when Price was changed
        }
    }
}
class Program
{
    static void Main()
    {
        clsItem myItem = new clsItem();
        myItem.Price = 123;   //this should trigger Event "onPriceChanged"
    }
    //EventHandler 
    public static void onPriceChanged()
    {
        Console.WriteLine("Price was changed");
    }
}

C#触发器事件

你这样做的方式不对——你试图从类中附加事件处理程序,显然这无法访问Program.onPriceChanged方法!

您应该公开您的事件,并从客户端代码(Program)附加事件处理程序。

class clsItem
{
    //private static event delEventHandler _show;
    private delEventHandler _show;
    private int _price;
    public clsItem()  //Konstruktor
    {
    }
    public event delEventHandler Show
    {
        add { _show += value; }
        remove { _show -= value; }
    }
    public int Price
    {
        set
        {
            _price = value;
            _show?.Invoke();  //trigger Event when Price was changed
        }
    }
}

和:

clsItem myItem = new clsItem();
myItem.Show += onPriceChanged;
myItem.Price = 123;   //this now does trigger Event "onPriceChanged" 

现场示例:http://rextester.com/WMCQQ40264

处理事件的方式不是一种好的做法。我们使用Events的原因是将我们创建的对象与它们需要调用的方法解耦。

例如,如果您想创建另一个相同类型的对象(clsItem),并在其价格更改后让它调用另一个方法,则会遇到麻烦。所以我建议使用这个代码而不是当前的代码:

using System;
public delegate void delEventHandler();
class clsItem
{
    public event delEventHandler PriceChanged;
    private int  _price;
    public clsItem()  //Konstruktor
    {
    }
    public int Price
    {
        set { 
              if(value!=_price) // Only trigger if the price is changed
              {
                _price = value;
                if(PriceChanged!=null) // Only run if the event is handled
                {
                    PriceChanged();
                }
              }
            }
    }   
}       
class Program
{   
    static void Main()
    {
       clsItem myItem = new clsItem();
       myItem.PriceChanged += new delEventHandler(onPriceChanged);
       myItem.Price = 123;   //this should trigger Event "PriceChanged" and call the onPriceChanged method
    }
    //EventHandler 
    public static void onPriceChanged()
    {
        Console.WriteLine("Price was changed");
    }
}

这里有一种更传统的做你想做的事情的方法:

public delegate void delEventHandler();
class clsItem
{
    public event delEventHandler Show;
    private int _price;
    public clsItem()  //Konstruktor
    {
    }
    public int Price
    {
        set
        {
            _price = value;
            Show?.Invoke();  //trigger Event when Price was changed
        }
    }
}
class Program
{
    static void Main()
    {
        clsItem myItem = new clsItem();
        myItem.Show += onPriceChanged;
        myItem.Price = 123;   //this should trigger Event "onPriceChanged"
    }
    //EventHandler 
    public static void onPriceChanged()
    {
        Console.WriteLine("Price was changed");
    }
}

请注意,clsItem不再知道谁在订阅其事件。它所关心的只是通知任何碰巧被订阅的侦听器。clsItemonPriceChanged方法之间不再存在依赖关系。