走向辉煌
你走不走?反正我走...

一、什么是委托

1.1官方解释

委托是一种定义方法签名的类型。当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。您可以通过委托实例调用方法。

1.2个人理解

委托就是执行方法(函数)的一个类。

事件是一种特殊的委托。

二、如何申明委托

2.1 delegate

        public delegate int TestDelegate(int x, int y);

2.2 Action

       Action是无返回值的泛型委托。

Action 表示无参,无返回值的委托

Action<int,string> 表示有传入参数int,string无返回值的委托

2.3 Func

Func是有返回值的泛型委托

Func<int> 表示无参,返回值为int的委托

Func<object,string,int> 表示传入参数为object, string 返回值为int的委托

2.4 predicate

predicate 是返回bool型的泛型委托

predicate<int> 表示传入参数为int 返回bool的委托。

2.5 四者之间的区别

Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型

Action至少1个参数,至多4个参数,无返回值,

Func至少0个参数,至多4个参数,根据返回值泛型返回。必须有返回值,不可void

Predicate至少1个参数,至多1个参数,返回值固定为bool

三、如何使用委托

3.1 Labmda表达式

TestDelegate d2= (string name) => { Console.WriteLine("你好,{0}!", name); };

d2("Terry");

3.2匿名方法

delegate void TestDelegate(string myName);

TestDelegate d2 = delegate(string name)
{

Console.WriteLine("Hello,{0}!", name);

};

d2(“Test”);

3.3 函数申明

private void DelegateMethod(string name)

{

Console.WriteLine("Hello,{0}!", name);

       }

       TestDelegate d2 = new TestDelegate(DelegateMethod);

       d2(“Test”);

四、使用委托有哪些特点

委托类似于 C++ 函数指针,但它们是类型安全的。

委托允许将方法作为参数进行传递。

委托可用于定义回调方法。

委托可以链接在一起;例如,可以对一个事件调用多个方法。

方法不必与委托签名完全匹配。

五、委托使用场景

委托一般都使用在 Observer模式(观察者模式)。

Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。

Observer模式主要包括如下两类对象:

被监视对象:往往包含着其他对象所感兴趣的内容。

监视者:当对象中的某件事发生的时候,会告知建设者,而建设者则会采取相应的行动。

例如:当你程序处理大批量数据时,需要在程序界面显示进度条进行友好提示,这时你通过委托来实现相当方便。

范例:

public delegate void DelegateMethod(int position, int maxValue);

  public class TestDelegate
    {
        public DelegateMethod OnDelegate;

        public void DoDelegateMethod()
        {
            int maxValue = 100;
            for (int i = 0; i < maxValue; i++)
            {
                if (this.OnDelegate != null)
                {
                    this.OnDelegate(i, maxValue);
                }
            }
        }

TestDelegate test = new TestDelegate();
            this.textBox1.Text = "";
            this.progressBar1.Value = 0;
            test.OnDelegate = new DelegateMethod(delegate(int i, int maxValue)
            {
                this.textBox1.Text += i.ToString() + Environment.NewLine;
                this.progressBar1.Maximum = maxValue;
                this.progressBar1.Value++;
            });
            test.DoDelegateMethod();

六、如何清空委托

1、在类中申明清空委托方法,依次循环去除委托引用。

         方法如下:

public class TestDelegate
    {
        public DelegateMethod OnDelegate;

                 public void ClearDelegate()
        {
            while (this.OnDelegate != null)
            {
                this.OnDelegate -= this.OnDelegate;
            }
        }
    }
2、如果在类中没有申明清空委托的方法,我们可以利用GetInvocationList查询出委托引用,然后进行去除。

方法如下:

TestDelegate test = new TestDelegate();

if (test.OnDelegate != null)
{
  System.Delegate[] dels = test.OnDelegate.GetInvocationList();
  for (int i = 0; i < dels.Length; i++)
  {
     test.OnDelegate -= dels[i] as DelegateMethod;
  }
}

 

插入

 

我在实际中用到的委托

声明:

 private delegate void fnShowItem();
  private Dictionary<String, fnShowItem> callShowItem;

 

实例:

callShowItem.Add("补充新员工资料", ShowItemForNewEmployee);
            callShowItem.Add("批量更改班次", ShowItemForShift);
            callShowItem.Add("批量更改主管", ShowItemForSuper);
            callShowItem.Add("批量更改资深主管", ShowItemForSrSuper);
            callShowItem.Add("批量更改组长", ShowItemForLeader);

 

实例:

  private void ShowItemForNewEmployee()
        {
            HideAll();

            this.cbBelongLocation.Visible = true;
            this.comboLine.Visible = true;
            // this.comboProcess.Visible = true;
            //  this.comboQuarters.Visible = true;
            //  this.comboCraftwork.Visible = true;
            this.txtBelongLeader.Visible = true;
            this.txtBelongSuper.Visible = true;

            //this.btn_SLeader.Visible = true;
            //this.btn_SSuper.Visible = true;

            //  this.txtQuartersKind.Visible = true;

            this.cbWIPInfo.Visible = true;

            this.btn_NewAdd.Visible = true;

            SetTipText("Default", Color.Maroon);
            SetSrSupervisor(" Where Mark = 'A' ");
        }

 

调用:

this.callShowItem["批量更改班次"]();

 

posted on 2012-10-08 09:36  b-韩非子  阅读(197)  评论(0编辑  收藏  举报