一个 有歧义 的 lambda 表达式

 今天发现了一句有歧义的labmbda表达式,发出来供大家“把玩”。

 先看引起“是非争端”的两个扩展方法:

 1       public   static   void  ForEach < T > ( this  IEnumerable < T >  source, Action < T >  action)
 2      {
 3           foreach  (T t  in  source) action(t);
 4      }
 5 
 6       public   static   void  ForEach < T > ( this  IEnumerable < T >  source, Func < T,  object >  func)
 7      {
 8           foreach  (T t  in  source) func(t);
 9      }

 第一个ForEach扩展不用多说;第二个比较怪吧,其实没必要存在,我也想不起来之前为什么就写了这么一个扩展。

 先别考虑第二个扩展的合理性,来看以下调用代码:

 1       public   class  People
 2      {
 3           public   string  Name {  get set ; }
 4           public   int  Age {  get set ; }
 5      }
 6 
 7       static   public   void  Test()
 8      {
 9          People[] peoples  =   new  People[]
10          {
11               new  People { Name  =   " ldp615 " },
12               new  People { Name =   " Tom " },
13               new  People { Name  = " Jim " }
14          };
15          peoples.ForEach(p  =>  p.Age = 20 );
16      }

 歧义在第15行,p => p.Age = 20。试问运行时会调用那个ForEach扩展呢??(先想想,答案在1楼

 

 两个ForEach,如果注释其中一个,代码同样能编译并运行,会自动匹配另外一个扩展。看来第15行有两重“含义”,如下:

1      peoples.ForEach(p  =>  { p.Age  =   20 ; });
2      peoples.ForEach(p  =>  {  return  p.Age  =   20 ; });

 以上两行代码中的lambda都可以简写成为 p => p.Age = 20,也就导致了歧义。

 

 那么在编译时,如何确定使用那个含义呢?应该看应用的上下文:

    1. 两个ForEach只保留一个时:使用与上下文相匹配的那含义(比较好理解)。
    2. 两个ForEach都存在时:我就不清楚了,可能是随机选一个吧,或者有优先级之说?(哪位高手知道,给俺说声)

 欢迎大家发表自己的看法。

你可能感兴趣的:(lambda)