请教个 泛型方法 泛型委托 匿名方法 扩展方法 lambda表达式 相关的一个难题。

时间:2022-05-10 17:34:49
泛型委托 public delegate TResult Func <T, TResult>(
T arg
)


 泛型方法:public static IEnumerable <TSource> Where <TSource>(
this IEnumerable <TSource> source,
Func <TSource, bool> predicate
)

----
应用
List <string> fruits = new List <string> { "apple", "passionfruit", "banana", "mango", 
                    "orange", "blueberry", "grape", "strawberry" };

IEnumerable <string> query = fruits.Where(fruit => fruit.Length  < 6);
foreach (string fruit in query)
    Console.WriteLine(fruit);

首先 lambda表达式如果换成匿名方法 delegate(string fruit){return fruit.Length  < 6;}这样对不对?
其次,目前我只能理解到,因为变量fruits,可以由编译器推出类型TSource 为string是吗?所以,委托Func <TSource, bool> predicate自然就推出是
Func <string, bool> predicate。然后就与对应的匿名方法delegate(string fruit){return fruit.Length  < 6;}在返回值与参数类型上一致了,是吧?
最后,我感觉,委托总要通过调用才能发挥作用的。 
string str="pea";
predicate(string str);//

可是,用了refelctor,没看到有类似的语句。
对于上面的例子,难道是foreach (string fruit in query) 这句才真正通过委托调用的方法吗?

==========================
大侠能不能举个简单的详细的例子来说明这一用法啊,我主要是对于泛型委托作为一个泛型方法的参数这种用法比较糊涂,不是理解不了委托作为参数,是理解不了具体是怎么实现的。
     

9 个解决方案

#1


该回复于2008-05-09 15:24:09被版主删除

#2


没人啊

#3


引用楼主 iloveppmm 的帖子:
对于上面的例子,难道是foreach (string fruit in query) 这句才真正通过委托调用的方法吗? 


是的。


引用楼主 iloveppmm 的帖子:
我主要是对于泛型委托作为一个泛型方法的参数这种用法比较糊涂,不是理解不了委托作为参数,是理解不了具体是怎么实现的。 


delegate声明的是普通的对象,对象可以被存储。方法和保存有方法的声明的对象不要混淆就行了。

#4


delegate声明的是普通的对象  -->  delegate声明的是普通的对象类型

#5


现在不理解的就是 匿名方法的参数x 是怎么赋的值并在扩展方法内部被定义好的委托调用的。

举个最简单的,

 delegate int addhandler(int a,int b);
 
 
 addhandler deladd=delegate(int x,int y){return x+y;}

 我们在实际应用的时候 不是应该有一句int i=deladd(3,6)// i=9对吧。
但是 在扩展方法里, 也应该是这样的形式。
 int c=3;
int d=6;
int i=deladd(c,d);***********
就是说,方法的代码中一定有类似的代码,最关键的就是deladd(c,d)这句,其中,c d 两个参数应该是外部传进去的。
但是,我不明白的是,lambda表达式相当于匿名方法,在我看来,就是直接在参数中定义了委托要调用的方法,但是,参数的值是从那传过去的呢? 

#6


当执行“IEnumerable  <string> query =....”那条语句的之后,query中保存着的是IQueable<string>类型的对象,其中它内部保存了Expression类型的lamda解析结果以及IQueryProvider类型的用来执行lamda的具体操作对象,但是只有到foreach执行时才会动态地由QueryPovider解释Expression来开始执行(参数此时传递)。为了“动态”,必须抓住Expression和IQueryProvider两条线分别保存对象,并且之后执行查询这个机制。而匿名方法则是相当静态的,是编译器翻译成很简单的匿名delegate对象以及插入执行代码,因此可以说与.net framework无关几乎只是一种“语言特色”,.net framework几乎无需支持。lamda则是很复杂的,必须从.net framework这一层就实现大量的内容(因此我不认为lamda“只不过是一堆语法糖”)。

#7


引用 5 楼 iloveppmm 的回复:
但是,我不明白的是,lambda表达式相当于匿名方法,在我看来,就是直接在参数中定义了委托要调用的方法,但是,.....


相似而已,机制完全不同。简单地应用一下匿名方法,只能适合内存中的可枚举对象集合操作而已。因此早已经有些语言实现了动态查询语法,但是未必真的能够实现linq这样的功能,只能算一点雏形,因为它们只能针对已经能够读取到内存中的可枚举对象集合操作。而lamda实际上对查询表达式翻译为一组内部动作,每一个内部动作具体如何执行则是很灵活的,例如Linq to SQL就可以把一个查询重新翻译为一组优化了的SQL,并动态地在运行时管理内部数据和执行这些SQL。

#8


不能转换,规则限制

#9


lambda表达式是匿名方法的一个特例,仅此而已,给分吧

#1


该回复于2008-05-09 15:24:09被版主删除

#2


没人啊

#3


引用楼主 iloveppmm 的帖子:
对于上面的例子,难道是foreach (string fruit in query) 这句才真正通过委托调用的方法吗? 


是的。


引用楼主 iloveppmm 的帖子:
我主要是对于泛型委托作为一个泛型方法的参数这种用法比较糊涂,不是理解不了委托作为参数,是理解不了具体是怎么实现的。 


delegate声明的是普通的对象,对象可以被存储。方法和保存有方法的声明的对象不要混淆就行了。

#4


delegate声明的是普通的对象  -->  delegate声明的是普通的对象类型

#5


现在不理解的就是 匿名方法的参数x 是怎么赋的值并在扩展方法内部被定义好的委托调用的。

举个最简单的,

 delegate int addhandler(int a,int b);
 
 
 addhandler deladd=delegate(int x,int y){return x+y;}

 我们在实际应用的时候 不是应该有一句int i=deladd(3,6)// i=9对吧。
但是 在扩展方法里, 也应该是这样的形式。
 int c=3;
int d=6;
int i=deladd(c,d);***********
就是说,方法的代码中一定有类似的代码,最关键的就是deladd(c,d)这句,其中,c d 两个参数应该是外部传进去的。
但是,我不明白的是,lambda表达式相当于匿名方法,在我看来,就是直接在参数中定义了委托要调用的方法,但是,参数的值是从那传过去的呢? 

#6


当执行“IEnumerable  <string> query =....”那条语句的之后,query中保存着的是IQueable<string>类型的对象,其中它内部保存了Expression类型的lamda解析结果以及IQueryProvider类型的用来执行lamda的具体操作对象,但是只有到foreach执行时才会动态地由QueryPovider解释Expression来开始执行(参数此时传递)。为了“动态”,必须抓住Expression和IQueryProvider两条线分别保存对象,并且之后执行查询这个机制。而匿名方法则是相当静态的,是编译器翻译成很简单的匿名delegate对象以及插入执行代码,因此可以说与.net framework无关几乎只是一种“语言特色”,.net framework几乎无需支持。lamda则是很复杂的,必须从.net framework这一层就实现大量的内容(因此我不认为lamda“只不过是一堆语法糖”)。

#7


引用 5 楼 iloveppmm 的回复:
但是,我不明白的是,lambda表达式相当于匿名方法,在我看来,就是直接在参数中定义了委托要调用的方法,但是,.....


相似而已,机制完全不同。简单地应用一下匿名方法,只能适合内存中的可枚举对象集合操作而已。因此早已经有些语言实现了动态查询语法,但是未必真的能够实现linq这样的功能,只能算一点雏形,因为它们只能针对已经能够读取到内存中的可枚举对象集合操作。而lamda实际上对查询表达式翻译为一组内部动作,每一个内部动作具体如何执行则是很灵活的,例如Linq to SQL就可以把一个查询重新翻译为一组优化了的SQL,并动态地在运行时管理内部数据和执行这些SQL。

#8


不能转换,规则限制

#9


lambda表达式是匿名方法的一个特例,仅此而已,给分吧