c#标准的事件定义与使用

上一篇博文中我写了一篇关于我对事件的理解和使用而那个是为了更好理解事件和认识他,但是一般的使用和.NET库中的事件使用的是标准的事件定义.

标准的 事件定义如下:

public delegate void Mydelegate(object sender,MyEventArgs e);

public event Mydelegate myevent;

委托类型的第一个参数表示的是当前事件发出者的实例对象.

其中第二个参数的类型MyEventArgs是一个继承自EventArgs的类;它主要是事件发出者用来向事件的订阅者传递数据用的.而EventArgs是.NET里面自带的类.

如下是我写的一个完整的 标准事件使用的例子:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{

class PubEventArgs : EventArgs//事件数据类
{
private readonly string m_magazineName;
private readonly DateTime m_pubDate;
public PubEventArgs(string mangazineName,DateTime pubDate)
{
m_magazineName = mangazineName;
m_pubDate = pubDate;

}
public string magazineName
{
get { return m_magazineName; }

}
public DateTime pubDate
{
get
{
return m_pubDate;
}

}

}
class Publisher//出版社类;
{
public delegate void PubComputerEventHandler(object sender, PubEventArgs e);//定义出版电脑杂志委托类型;
public delegate void PubLifeEventHandler(object sender, PubEventArgs e);//定义出版生活杂志委托类型;
public event PubComputerEventHandler pubComputer;//出版电脑杂志事件;
public event PubLifeEventHandler pubLife;//出版生活杂志事件;

protected virtual void OnPubComputer(PubEventArgs e)//虚方法用来调用触发事件传递事件数据;
{
PubComputerEventHandler handler = pubComputer;
if (handler != null)
handler(this, e);

}
protected virtual void OnPubLife(PubEventArgs e)//虚方法用来调用触发事件传递事件数据;
{
PubLifeEventHandler handler = pubLife;
if (handler != null)
handler(this, e);

}
public void issueComputer(string name, DateTime date)//触发事件方法;
{
Console.WriteLine("发行" + name);
OnPubComputer(new PubEventArgs(name, date));
}
public void issueLife(string name, DateTime date)//触发事件方法;
{
Console.WriteLine("发行" + name);
OnPubLife(new PubEventArgs(name, date));
}

}
class Subscriber//订阅者类;
{

private string name;
public Subscriber(string objname)
{
this.name = objname;
}
public void Receiver(object sender,PubEventArgs e)//订阅者处理方法;
{
Console.WriteLine(this.name+"已订阅" + e.magazineName+" "+e.pubDate);
}

}

class Program
{
static void Main(string[] args)
{
Subscriber sub1 = new Subscriber("fgreen");//订阅者1;
Subscriber sub2 = new Subscriber("ty");//订阅者2;

Publisher pub = new Publisher();//出版社对象;
pub.pubComputer += new Publisher.PubComputerEventHandler(sub1.Receiver);//订阅者1 订阅电脑杂志;
pub.pubLife += new Publisher.PubLifeEventHandler(sub1.Receiver);//订阅者1 订阅生活杂志;

pub.pubLife += new Publisher.PubLifeEventHandler(sub2.Receiver);//订阅者2 订阅生活杂志
//订阅者2并没有订阅电脑杂志;

pub.issueComputer("电脑杂志", Convert.ToDateTime("2015-5-13"));//出版社发行电脑杂志;
pub.issueLife("生活杂志", Convert.ToDateTime("2015-5-13"));//出版社发行生活杂志;
Console.ReadLine();

}
}
}

我对c#事件的理解

在C#里面 事件就是类在发生它关注的事情时用来提供通知的一种方式,

所有的事件都依托于委托因为声明一个事件必须为其声明委托类型,它是由委托来进行激活的.

如声明一个事件

public delegate void Mydelegate();//声明事件委托类型 ;

public event Mydelegate Myevent;//声明事件;

 

一般在声明事件的类中要包含触发事件的方法,因为创建事件的类就相当于出版社,而它的一个事件就相当于它具体要出版哪一本书,

而触发事件就是出版社要在什么时候出版这本书.而此书的订阅者则是此事件的事件处理对象,具体的事件处理程序则需要订阅者自己定义;

 

如以下程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication4
{
public delegate void Mydelegate();

class publish
{
public event Mydelegate myevent;
public void issue()//定义类调用触发事件的方法;
{

if(myevent!=null)
myevent();//触发事件;

}
}

class Order
{
private string productnName;
private int productID;
public Order(string name,int id)
{

this.productnName = name;
this.productID = id;
}
public void Product()
{
Console.WriteLine(“已下单 产品名称:{0},产品ID:{1}”, productnName, productID);

}

}
class Program
{
static void Main(string[] args)
{
publish pub = new publish();//供货商;
Order people1=new Order(“小米2s”,100);//消费者1需要小米2S;
Order people2 = new Order(“苹果5s”, 1000);//消费者2需要苹果5S;
pub.myevent += new Mydelegate(people1.Product);//people1订货;

pub.myevent += new Mydelegate(people2.Product);//people2订货;
pub.issue();//发货;
Console.ReadLine();
}

 

}
}

执行后如下显示.

 

 

上面的程序表达了一个供货商或厂商直接像消费者提供订货渠道,然后由订货者自己订货,只有供货商自己才能发货也就是说事件的定义者自己才能

触发事件,而事件处理程序由事件的订阅者定义.

 

 

 

 

c#里的委托

最近在学习c#但是里面的委托和事件只是一个比较难理解的知识点,我觉得委托就是类似c/c++里面的函数指针,声明一个委托就类似于声明一个委托类型.

而在c#中委托类型是静态的它并不属于某个类对象,他可以定义在类内可以可以定义在类外,在类内部定义时需要用类名进行引用.

定义 委托类型:

如  public delegat void  Mydelegate();这就相当于在c/c++定义了一个公有类型的 无返回值 无参数的 函数指针.

只是在c#中它可以作为一个类型 去定义一个变量,这个变量就是一个函数的引用也就是函数的指针,

如   用创建的委托类型去创建一个委托变量和给委托变量赋值 Mydelegate  test=new Mydelegate(函数名);

给委托变量赋值 实际上就是给这个变量赋一个或开辟一个函数的内存空间,而括号内的函数名就是你所定义的函数,此函数必须和你定义的

委托类型一样,如委托类型是 无返回值,无参数的那么你所定义的函数也必须和此类型相同才能正确初始化委托变量.

如需要使用它则直接像使用函数那样 使用这个委托.

当然你还可以 直接使用匿名方法给委托变量赋值这就相当于在定义数组的时候直接赋初值.

还可以给委托对象添加多个调用方法如;