C#-委托与事件

一、 什么是委托:
大家先看一个示例:
下面类中是两个函数,分别实现的二倍,和平方的功能
class MathsOperations
{
public static double MultiplyByTwo(double value)
{
return value*2;
}
public static double Square(double value)
{
return value*value;
}
}
在下面代码中,我们需要多次调用这两个函数(大家想以一下按以前的方法调用我们应该如何写代码)
using System;
namespace SimpleDelegate
{
delegate double DoubleOp(double x);
class MainEntryPoint
{
static void Main()
{
DoubleOp [] operations =
{
new DoubleOp(MathsOperations.MultiplyByTwo),
new DoubleOp(MathsOperations.Square)
};
for (int i=0 ; i<operations.Length ; i++)
{
Console .WriteLine(“Using operations[{0}]:”, i);
ProcessAndDisplayNumber(operations[i], 2.0);
ProcessAndDisplayNumber(operations[i], 7.94);
ProcessAndDisplayNumber(operations[i], 1.414);
Console .WriteLine();
}
}
static void ProcessAndDisplayNumber(DoubleOp action, double value)
{
double result = action(value);
Console .WriteLine(
“Value is {0}, result of operation is {1}”, value, result);
}
 
下面是一个冒泡排序的函数
 
//void Boble(int[] sortArray) 可能不一定传入整型
for (int i = 0; i < sortArray.Length; i++)
{
for (int j = i + 1; j < sortArray.Length; j++)
{
if (sortArray[j] < sortArray[i]) // 比较的如果是自定义类型又如何?
{
int temp = sortArray[i]; // 交换的类型如果是其它类型?
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
 
看下面的代码,可以对所有类型的数据进行排序
class BubbleSorter
{
static public void Sort(object [] sortArray, CompareOp gtMethod)
{
for (int i=0 ; i<sortArray.Length ; i++)
{
for (int j=i+1 ; j<sortArray.Length ; j++)
{
if (gtMethod(sortArray[j], sortArray[i]))
{
object temp = sortArray[i];
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
}
}
 
定义自定义的类,完成员工按工资进行排序
class Employee
{
private string name;
private decimal salary;
public Employee(string name, decimal salary)
{
this .name = name;
this .salary = salary;
}
public override string ToString()
{
return string.Format(name + “, {0:C}”, salary);
}
public static bool RhsIsGreater(object lhs, object rhs)
{
Employee empLhs = (Employee) lhs;
Employee empRhs = (Employee) rhs;
return (empRhs.salary > empLhs.salary) ? true : false;
}
}
using System;
namespace Wrox.ProCSharp.AdvancedCSharp
{
delegate bool CompareOp(object lhs, object rhs);
class MainEntryPoint
{
static void Main()
{
Employee [] employees =
{
new Employee(“Bugs Bunny”, 20000),
new Employee(“Elmer Fudd”, 10000),
new Employee(“Daffy Duck”, 25000),
new Employee(“Wiley Coyote”, (decimal)1000000.38),
new Employee(“Foghorn Leghorn”, 23000),
new Employee(“RoadRunner’”, 50000)};
CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsGreater);
BubbleSorter.Sort(employees, employeeCompareOp);
for (int i=0 ; i<employees.Length ; i++)
Console.WriteLine(employees[i].ToString());
}
}
如果我们要排序的产品的大小(以库存或价格排序),又如何实现
关于对象排序,还有没有其它方法
可能的答案:重载比较操作符
 
必须成对重载
public static bool operator == (Employee e1, Employee e2)
{
if (e1.salary==e2.salary)
return true;
else
return false;
}
public static bool operator != (Employee e1, Employee e2)
{
if (e1.salary!=e2.salary)
return true;
else
return false;
}
public static bool operator < (Employee e1, Employee e2)
{
if (e1.salary<e2.salary)
return true;
else
return false;
}
public static bool operator > (Employee e1, Employee e2)
{
if (e1.salary>e2.salary)
return true;
else
return false;
}
小结:
委托是对相同参数和返回值的函数,可以交给一个对象支统一调用,可以重用代码
 
二、 多次委托:
DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo);
operations += new DoubleOp(MathOperations.Square);
 
DoubleOp operation1 = new DoubleOp(MathOperations.MultiplyByTwo);
DoubleOp operation2 = new DoubleOp(MathOperations.Square);
DoubleOp operations = operation1 + operation2;
 
执行:Operations(3)
 
结果是什么?
分别调用了二倍和平方算法
小结:这样可以多次给委托对象赋值,然后一次输出
 
三、 事件
C#中的事件机制是通过委托来实现的
我们看一个例子:以上面的员工类为例
class Employee
{
private string name;
private decimal salary;
public Employee(string name, decimal salary)
{
this .name = name;
this .salary = salary;
}
public override string ToString()
{
return string.Format(name + “, {0:C}”, salary);
}
public void save()
{
     //code1
     Console.WriteLine(name+”is saved”);
}
}
 
当我们希望在保存前能提示用户输入的信息时我们怎么做,我们在code1处加上一段代码
Console.WriteLine(“now is Saving data!,please wait”);
这样虽然可以,但这个类编译以后,代码就定死了不好改动了,如能在客户端给出回调代码则是较好的设计。
 
Using System;
Public delegate void EventHandle(); //1
 
class Employee
{
//略
 
public event EventHandle beforeSave; //2
 
public void save()  
{
     //code1
     if(beforeSave!=null)
          beforeSave();      //4
     Console.WriteLine(name+”is saved”);
}
}
 
class Demo
{
     public static void Main()
     {
          Employee emp = new Employee(“”,”ddd”);
          Emp.beforeSave+=new EventHandle(MyBeforeSave);   //5
          Emp.save();
     }
     static void MyBeforeSave()   //6
     {
          Console.WriteLine(“now is Saving.wait please”);
     }
}
 
事件:
1. 定义一个公共委托方法Public delegate void EventHandle();
2. 在组件中用委托声明事件public event EventHandle beforeSave;
3. 增加事件注册和移除的方法   //可不用
4. 在要调用的方法前后加上委托的方法调用public void save()
5. 在客户端注册事件Emp.beforeSave+=new EventHandle(MyBeforeSave);
6. 在客户端写被委托的方法内容static void MyBeforeSave()
 
客户工程代码如下:
using System;
using System.Collections.Generic;
using System.Text;
 
namespace DelegateDemo
{
    class Program
    {
     public static void Main()
     {
          Employee emp = new Employee("gobn",new Decimal(123.34));
          emp.beforeSave+=new EnventHandle(MyBeforeSave);   //5
          emp.save();
        Console.ReadLine();
     }
     static void MyBeforeSave()   //6
     {
          Console.WriteLine("now is Saving.wait please");
     }
 
    }
}
 
 
Employee类如下
using System;
using System.Collections.Generic;
using System.Text;
 
namespace DelegateDemo
{
    public delegate void EnventHandle();
    class Employee
    {
        private string name;
        private decimal salary;
        public Employee(string name, decimal salary)
        {
            this.name = name;
            this.salary = salary;
        }
        public event EnventHandle beforeSave; //2
 
        public void save()  
        {
             //code1
             if(beforeSave!=null)
                 beforeSave();      //4
             Console.WriteLine(name+" is saved");
        }
 
    }
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值