c#有一个很重要的高级语言特性,叫做事件,有很多人说事件就是委托,其实不然,事件包含委托,但绝对不是委托,因为事件只能在类中声明,而委托可以在函数也就是方法中声明,另外,事件的方法也少于委托,那么什么是事件呢,使用事件,需要在类中声明,并且事件始终是共有方法,而且使用事件需要在类型前加上event,而且事件类型一定是一个委托类型。
那么什么是委托呢,委托其实类似于c语言和c++语言的函数指针,因为c#中取消了指针,所以就不存在函数指针的概念了,因为函数指针也是一种指针,但是函数指针很有用处,比如你给一个函数传递一个函数指针,而此函数的数据是不变的,这样就可以动态改变函数中的数据,因为传入的函数指针变化,c#加入了委托概念,委托是类型安全,事实上,委托是一个类,委托类似函数指针,不了解委托概念的人可以了解函数指针。
delegate void mydelegate(int x);//首先在使用事件之前,必须定义一个委托,以后事件的注册函数必
//须于此委托函数签名一致
class publisher//发布者
{
public event mydelegate myevent;//事件出现在类中,必须共有,加上事件公共字,并使用委
//托类型
public void Startup()
{
for(int i=0;i<100;++i)
{
if(i%12==0&&myevent!=null)
{
myevent(i);//调用事件方法
}
}
}
}
class subcribe//订阅者
{
public subcribe(publisher pb) { pb.myevent += regisiterfunc; }//发布者与订阅者结合
public int Id { get;private set; }
public void regisiterfunc(int x)//订阅者提供事件所需的注册函数
{
Id++;
Console.WriteLine(Id);
Console.WriteLine("code id={0}", x);
Console.WriteLine("___________");
}
}
大家可以看到,使用事件必须要五个步骤,这五个步骤不能少,首先,1,定义委托类型,2,在一个类也就是发布者定义事件,3,在发布者中调用事件,当然是在合适的时机,然后还有两个步骤,即在订阅者,4,也就是另外一个至少一个或很多的类中提供事件所需,且与事件签名一模一样的注册函数,另外,5,需要在订阅者中导入发布者类的事件接口,使得两者咬合。
现在在看一个具体的例子,完全是我自己原创:
delegate int mydelegate1(object o);//定义委托
class myDefineArgs : EventArgs//这个类可以用于事件参数,也可不用
{
public myDefineArgs(string name,double price) { Name = name;Price = price; }
public string Name { get; set; }
public double Price { get; set; }
}
class shop
{
public event mydelegate1 myevent;//定义事件
public void updateprice(customer c,customer1 c1)//事件启发函数
{
while (true)
{
int i = -1;
i = Convert.ToInt32(Console.ReadLine());//与下面的效果一样
// i = System.Int32.Parse(Console.ReadLine());
if (i == 0)
{
myevent -= c.testfunc;
myevent(this);
myevent += c.testfunc;
}
else if (i == 1)
{
myevent -= c1.myregisterfunc;
myevent(this);
myevent += c1.myregisterfunc;
}
}
}
}
//然后下面在写两个类,这两个类有相同部分,比如全部是消费者类,与超市类对应,但是这两个消费者类各有不同,因此写成两个,因为提供注册的事件函数不同,这样可以减少代码复杂度,即两个发布者提供注册函数,分别与shop中的事件链接,然后再shop中集中处理
class customer
{
public customer(shop s) { s.myevent+=testfunc; }
public List<myDefineArgs> buygoods = new List<myDefineArgs>();
public int testfunc(object o)
{
foreach (var arg in buygoods)
{
Console.WriteLine(o.ToString());
if (arg.Price > 1000)
{
Console.WriteLine("expensive goods {0} {1}", arg.Name, arg.Price);
}
else if (arg.Price <= 1000)
{
Console.WriteLine("cheap goodes {0} {1}", arg.Name, arg.Price);
}
}
return 0;
}
}
class customer1
{
public List<myDefineArgs> buygoods = new List<myDefineArgs>();
public customer1(shop s) { s.myevent += myregisterfunc; }
public int myregisterfunc(object o)
{
foreach (var arg in buygoods)
{
switch (arg.Name)
{
case "football": Console.WriteLine("footaball {0}", arg.Price); break;
case "basketball": Console.WriteLine("bascket {0}", arg.Price); break;
default: break;
}
}
return 0;
}
}