(11)委托和Lamda表达式

**委托(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();
        }
    }
}
**匿名方法:就是没有实际方法声明委托实例,或者说,他们的定义是直接内嵌在代码中的。

        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语句

            BubbleSort(items,
                delegate(int first, int second)
            {
                return first < second;
            });
与上述等价的 Lamda语句(用于)

            BubbleSort(items,
                (int first, int second)=>
                {
                    return first < second;
                }
            );
*省略参数类型:通常,只要编译器能推断出参数类型,或者能将参数类型隐式转换成期望的数据类型,语句Lamda就不需要参数类型。如果要制定类型,那么制定的类型必须和委托类型完全匹配。只要Lamda语句包含了一个类型,则所有的类型都要加上。

            BubbleSort(items,
                (first,second)=>
                {
                    return first < second;
                }
            );
*c#要求用一对圆括号来封闭Lamda表达式的参数类表,不管是否指定了这些参数的数据类型。圆括号的另外一个规则是,当编译器能推断出数据类型,而且只有一个输入参数的时候,语句Lamda可以不带圆括号。

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'


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值