**委托(delegate):一个表示方法的数据类型。间接派生于System.Delegate
委托是一个引用类型,但不必用new来实例化它。直接传递名称,而不是现实实例化。这是c#2.0开始支持的一个新语法,成为委托推断(delegate inference)
- namespace delegateEx
- {
- //委托声明
- public delegate bool ComparisonHandler(int first,int second);
- public static class DelegateSample
- { //
- public static void BubbleSort(int[] items, ComparisonHandler comparisonMethod)
- {
- int i;
- int j;
- int temp;
- if (items == null)
- {
- return;
- }
- if (comparisonMethod == null)
- {
- throw new ArgumentNullException("comparisonMethod");
- }
- for (i = items.Length - 1; i >= 0; i--)
- {
- for (j = 1; j <= i; j++)
- {
- //用委托实例
- if (comparisonMethod(items[j - 1], items[j]))
- {
- temp = items[j - 1];
- items[j - 1] = items[j];
- items[j] = temp;
- }
- }
- }
- }
- //匹配委托的参数GreaterThan(int first, int second)
- public static bool GreaterThan(int first, int second)
- {
- return first > second;
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- int[] items = new int[100];
- Random random = new Random();
- for (int i = 0; i < items.Length; i++)
- {
- items[i] = random.Next(1,100);
- }
- //将委托实例作为参数传递
- DelegateSample.BubbleSort(items, DelegateSample.GreaterThan);
- for (int i = 0; i < items.Length; i++)
- {
- Console.Write(" {0}",items[i]);
- }
- Console.ReadKey();
- }
- }
- }<strong>
- </strong>
- static void Main(string[] args)
- {
- int[] items = new int[5];
- Random random = new Random();
- ComparisonHandler comparisonMethod;
- for (int i = 0; i < items.Length; i++)
- {
- items[i] = random.Next(1, 100);
- }
- //委托的定义直接内嵌在代码中。
- comparisonMethod = delegate(int first, int second)
- {
- return first < second;
- };
- BubbleSort(items,comparisonMethod);
- for (int i = 0; i < items.Length; i++)
- {
- Console.Write(" {0}", items[i]);
- }
- Console.ReadKey();
- }
- BubbleSort(items,
- delegate(int first, int second)
- {
- return first < second;
- });
注意,在任何情况下,参数和返回值类型必须兼容于委托的数据类型。
*匿名方法是允许省略参数列表的,但是返回值类型需要与委托一致。
**系统定义的委托:
System.Func 在.NET 3.5中代表有返回类型的委托
System.Action代表无返回类型的委托。
不能将一个委托类型赋给另一个委托类型的变量,即使类型参数匹配。
*为委托使用可变性[还没理解]
Action<object> broadAction=delegate(object data)
{
Console.WriteLine(data);
}
Action<string> narrowAction=broadAction;
Func<string>narrowFunction=delegate()
{
return Console.WriteLine();
};
Func<object> broadFunction=narrowAction;
Func<object ,string >func1=
degate(object data)
{
return data.ToString();
};
Func<string,object>func2=fun1;
**Lamda表达式 (关键字=>) :分为Lamda表达式和Lamda语句
- <strong> </strong> BubbleSort(items,
- delegate(int first, int second)
- {
- return first < second;
- });
- BubbleSort(items,
- (int first, int second)=>
- {
- return first < second;
- }
- );
- BubbleSort(items,
- (first,second)=>
- {
- return first < second;
- }
- );
Func<string> getUserInput=
()=>
{
string input;;
do
{ input=Console.ReadLine();}
while(input.Trim()==0);
return input;
}
*Lamda表达式(满足……条件)
- BubbleSort(items,
- (int first, int second)=> first < second );
**Lamda表达式本身没有类型
所以 . 运算符不会被编译,调用Object的方法也不行。
不能出现在is的左侧
Lamda表达式一旦被赋值或者转型,就会有Lamda表达式的类型这种非正式的说法
不能赋值给隐式类型的变量
如果目的在Lamda表达式的外部,c#就不允许在匿名函数内部使用跳转语句(break,continue,goto)
*外部变量:在Lamda表达式(包括参数)的外部声明,但是Lamda表达式的内部捕捉(访问)的局部变量称为外部变量。this也是一个外部变量。
int comparisonCount=0;
...
BubbleSort(item,
(int first ,int second)=>
{
comparisonCount++;
return first<second;
}
);
Console.WriteLine(comparisonCount);
**表达式树[不理解]
“解释”是c#引入表达式树(expression trees)这一概念的重要动机。如果一种Lamda表达式代表的是与表达式有关的数据,而不是编译好的代码,这中Lamda表达式就是表达式树。由于表达式树代表的是数据而非编译好的代码,所以可以把数据转换成一种替代格式。例如,转换成SQL代码。
persons.Where(person=>person.Name.ToUpper()=="INIGO MONTOYA")
select *from Person where upper(Name)='INIGO MONTOYA'