C# 支持用于调用一个或多个方法的委托 (delegate)。委托提供运算符和方法来添加或删除目标方法,它也可以在整个 .NET 框架中广泛地用于事件、回调、异步调用、多线程等。然而,仅仅为了使用一个委托,有时不得不创建一个类或方法。 public delegate void SetDataGridView(DataTable tableResult);

public partial class Form_Main : Form

{

     private SetDataGridView  delegate_SetDataGridView = null;

 

    private void SetDataGridView(DataTable tableResult)

    {

      this.delegate_SetDataGridView = new   SetDataGridView(SetDataGridView);

    }

 

}

      例如在winForm页面上启动一个线程,做复杂计算,然后要在界面上刷新结果。那么在.net2.0 线程安全机制下,就不得不调用一个委托(因.net 2.0 线程安全机制要求使用委托来访问UI控件)。 

因此,我们看到一个完整的委托需要这样声明。

 

        public delegate void MyDelegate();

 

        public void UserDelegate()

     {

            MyDelegate myDelegate = new MyDelegate(this.MethodDelegate);

        }

 

        private void MethodDelegate()

       {

             //do something       

       }

           但在.net 2.0 下,您就可以简洁、方便的来给委托指定方法了

 

 第一种形式:直接给委托指定函数。这种形式下,等号右边可以是个直接的函数名,而不是用new关键词来声明一个委托对象。

DelegateInt delegateInt = this.TestInt;

 

 第二种形式:直接用delegate声明一个方法体,这样的方法称为内嵌方法delegate后()中是该方法的参数;而方法的返回值由return语句。编译器将根据方法体的返回值判断是不是和委托的定义一致

 

delegateInt = delegate(int num)

{

   return num = num+2;

};

 

 第三种形式:在采用第二种方式的情况下,不声明参数,委托的参数将被编译器视而不见。

 

int foreignNum = 0;

delegateInt = delegate

{

 return 21 + foreignNum;

};

 

       那采用这种匿名这种形式有什么好处呢?难道微软让编译器实现复杂的推理编译,只是让代码变得飘忽?

 

      那么让我们来看一段代码。如果您对这段代码不是很理解,可以参考一下BQMGSR 项目分享之谓词详解

 

          //生成一个数例           

           List<int> listNumber = this.InitalList();

           // 初始index           

           int index = 1;

           // 用ConvertAll<T>转成一个带提示信息的List<string>   匿名委托           

          List<string> listText = listNumber.ConvertAll<string>(delegate(int value)

          {

                return "第" + (index++).ToString() + "个数是:" + value.ToString() + ""n";

            });

            this.richTextBox1.Clear();

           //用foreach输出           

            foreach (string text in listText)

            {

                this.richTextBox1.AppendText(text);

            }

    

 

这段代码将一个数列加上第? 个数是:的提示后输出。试着考虑这样的问题,ConvertAll<T>方法定义的参数Converter已经定义了两个泛型参数,TInput,TOutput分别表示原始List<T>的T类型参数和返回时的List<P>类型参数,除此之外就没有其他的参数了。那我怎么知道当前的这个数值是第几号呢?

 

public delegate TOutput Converter<TInput, TOutput>(TInput input);

     那上面那段代码什么怎么解决的呢?可以看到在内嵌方法中调用了一个在方法外部定义的变量index,并将这个值+1,这就是匿名委托的神奇之处。传统的委托方式,完全是调用一个新的方法,传什么参数,返回什么类型早已定好,你无法再增加参数。因而你如果用像谓词这样早就定义好的委托,那你的双手就被束缚了。

 

    看来微软早就发现了这个问题,因而推出了匿名委托来解决。匿名委托中的内嵌方法其实不是一个严格意义上的方法,而只是一个被重用的代码段,没有重新建立数据环境。因而事实上匿名委托和传统意义上的委托不是完全一致的。

 

    匿名委托带来的不只是优美