Events:
It is basically used for subscriber/publisher model.
subscriber of any delegate function can be declared as an event. In such case, Any operation can be done on the event inside the class, however only += and -+ can be done outside the class. eg:
public delegate void PriceChangedHandler();
class{
public event PriceChangedHandler PriceChanged;
}
Here inside the class we can do any operation on the PriceChanged but outside the class we can just do += and -=;
Standard event pattern:
Class extends System.EventArgs. It just contains some empty static property
Next create delegate: return type should be void. It must accept 2 parameters. First is object type. Second is subclass of EventArgs. Its name must end in "EventHandler"
eg public delegate void EventHandler<TEventArgs>
(object source, TEventArgs e) where TEventArgs : EventArgs;
Next define event: public event EventHandler<PriceChangedEventArgs> PriceChanged;
Finally, the pattern requires that you write a protected virtual method that fires the event. The name must match the name of the event, prefixed with the word"On", and then accept a single EventArgs argument: eg : protected virtual void OnPriceChanged (PriceChangedEventArgs e)
{
if (PriceChanged != null) PriceChanged (this, e);
}
Sample program:
using System;
public class PriceChangedEventArgs : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice;
public PriceChangedEventArgs (decimal lastPrice, decimal newPrice)
{
LastPrice = lastPrice; NewPrice = newPrice;
}
}
public class Stock
{
string symbol;
decimal price;
public Stock (string symbol) {this.symbol = symbol;}
public event EventHandler<PriceChangedEventArgs> PriceChanged;
protected virtual void OnPriceChanged (PriceChangedEventArgs e)
{
if (PriceChanged != null) PriceChanged (this, e);
}
public decimal Price
{
get { return price; }
set
{
if (price == value) return;
OnPriceChanged (new PriceChangedEventArgs (price, value));
price = value;
}
}
}
class Test
{
static void Main( )
{
Stock stock = new Stock ("THPW");
stock.Price = 27.10M; //1
// register with the PriceChanged event
stock.PriceChanged += stock_PriceChanged; //2
stock.Price = 31.59M; //3
stock.Price = 31.59M; //4
stock.Price = 35.69M; //5
stock.PriceChanged -= stock_PriceChanged; //6
stock.Price = 37.89M;//7
}
static void stock_PriceChanged (object sender, PriceChangedEventArgs e)
{
if ((e.NewPrice - e.LastPrice) / e.LastPrice > 0.1M)
Console.WriteLine ("Alert, 10% stock price increase!");
}
}
In this program, executino starts with main. value of Price is set at 1. Since there is price change, it will call OnPriceChanged. Inside this funciton, since PriceChanged is null, it is not doing anything. At 2, It is adding method stock_PriceChanged to PriceChanged. Notice stock_PriceChanged is static with void return type. At 3, it is again setting value of Price and which is calling OnPriceChanged. Now PriceChanged is not null. So PriceChanged is called which actually is calling stock_PriceChanged with arguments of type object and PriceChangedEventArgs(subclass of EventArgs). At 4, there is no price change, so it returns. 5 is same as 3. At 6, function stock_PriceChanged is removed from PriceChanged event. So in 7, stock_PriceChanged is not called.
If we don't need any other information other than just that event is fired, we can use EventArgs.Empty
eg: Lets modify Stock class to incorporate this:
public class Stock
{
string symbol;
decimal price;
public Stock (string symbol) {this.symbol = symbol;}
public eventEventHandler PriceChanged;
protected virtual void OnPriceChanged (EventArgs e)
{
if (PriceChanged != null) PriceChanged (this, e);
}
public decimal Price
{
get { return price; }
set
{
if (price == value) return;
price = value;
OnPriceChanged (EventArgs.Empty);
}
}
}
It is basically used for subscriber/publisher model.
subscriber of any delegate function can be declared as an event. In such case, Any operation can be done on the event inside the class, however only += and -+ can be done outside the class. eg:
public delegate void PriceChangedHandler();
class{
public event PriceChangedHandler PriceChanged;
}
Here inside the class we can do any operation on the PriceChanged but outside the class we can just do += and -=;
Standard event pattern:
Class extends System.EventArgs. It just contains some empty static property
Next create delegate: return type should be void. It must accept 2 parameters. First is object type. Second is subclass of EventArgs. Its name must end in "EventHandler"
eg public delegate void EventHandler<TEventArgs>
(object source, TEventArgs e) where TEventArgs : EventArgs;
Next define event: public event EventHandler<PriceChangedEventArgs> PriceChanged;
Finally, the pattern requires that you write a protected virtual method that fires the event. The name must match the name of the event, prefixed with the word"On", and then accept a single EventArgs argument: eg : protected virtual void OnPriceChanged (PriceChangedEventArgs e)
{
if (PriceChanged != null) PriceChanged (this, e);
}
Sample program:
using System;
public class PriceChangedEventArgs : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice;
public PriceChangedEventArgs (decimal lastPrice, decimal newPrice)
{
LastPrice = lastPrice; NewPrice = newPrice;
}
}
public class Stock
{
string symbol;
decimal price;
public Stock (string symbol) {this.symbol = symbol;}
public event EventHandler<PriceChangedEventArgs> PriceChanged;
protected virtual void OnPriceChanged (PriceChangedEventArgs e)
{
if (PriceChanged != null) PriceChanged (this, e);
}
public decimal Price
{
get { return price; }
set
{
if (price == value) return;
OnPriceChanged (new PriceChangedEventArgs (price, value));
price = value;
}
}
}
class Test
{
static void Main( )
{
Stock stock = new Stock ("THPW");
stock.Price = 27.10M; //1
// register with the PriceChanged event
stock.PriceChanged += stock_PriceChanged; //2
stock.Price = 31.59M; //3
stock.Price = 31.59M; //4
stock.Price = 35.69M; //5
stock.PriceChanged -= stock_PriceChanged; //6
stock.Price = 37.89M;//7
}
static void stock_PriceChanged (object sender, PriceChangedEventArgs e)
{
if ((e.NewPrice - e.LastPrice) / e.LastPrice > 0.1M)
Console.WriteLine ("Alert, 10% stock price increase!");
}
}
In this program, executino starts with main. value of Price is set at 1. Since there is price change, it will call OnPriceChanged. Inside this funciton, since PriceChanged is null, it is not doing anything. At 2, It is adding method stock_PriceChanged to PriceChanged. Notice stock_PriceChanged is static with void return type. At 3, it is again setting value of Price and which is calling OnPriceChanged. Now PriceChanged is not null. So PriceChanged is called which actually is calling stock_PriceChanged with arguments of type object and PriceChangedEventArgs(subclass of EventArgs). At 4, there is no price change, so it returns. 5 is same as 3. At 6, function stock_PriceChanged is removed from PriceChanged event. So in 7, stock_PriceChanged is not called.
If we don't need any other information other than just that event is fired, we can use EventArgs.Empty
eg: Lets modify Stock class to incorporate this:
public class Stock
{
string symbol;
decimal price;
public Stock (string symbol) {this.symbol = symbol;}
public eventEventHandler PriceChanged;
protected virtual void OnPriceChanged (EventArgs e)
{
if (PriceChanged != null) PriceChanged (this, e);
}
public decimal Price
{
get { return price; }
set
{
if (price == value) return;
price = value;
OnPriceChanged (EventArgs.Empty);
}
}
}