代码改变世界

LINQ 笔记- Lambda

2008-02-21 23:11  Animax!  阅读(586)  评论(2编辑  收藏  举报

先记录一下C# 3.0 中的新功能。


隐式类型化变量:

不在声明并初始化变量时显式指定类型,让编译器推断函数类型。
var T1 = 5// T1的类型就是int, 和 int T1 = 5; 是完全相同的



属性的自动实现:

当属性访问器不需要其他逻辑的时候,可以通过下面的方法减少代码的编写。
class LightweightCustomer
{
    
public double TotalPurchases getset; }
    
public string Name getprivate set; } // 只读
    public int CustomerID getprivate set; } // 只读
}



对象和集合初始值设定项:

通过对象和集合初始值设定项,初始化对象时无需为对象显式调用构造函数。
public class T 
{
    
public int T1 getset; }     //属性的自动实现  
    public string T2 getset; }  
}


static void Main()
{
    T NewT 
= new T { T1 = 10, T2 = "NewT" }//设定初始值
    
//
}




匿名类型:

匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。
var v = new { Amount = 108, Message = "Hello" };

匿名类型需要配合隐式变量来使用。



匿名函数:

匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用。可以使用匿名函数来初始化命名委托,或传递命名委托(而不是命名委托类型)作为方法参数。
class Test
{
    
delegate void TestDelegate(string s);   //最初的委托方式, 声明一个委托
    static void M(string s)                 //最初的委托方式, 一个被委托的方法
    {
        Console.WriteLine(s);
    }


    
static void Main(string[] args)
    
{
        
// C# 1.0 最初的委托方式 
        TestDelegate testdelA = new TestDelegate(M);

        
// C# 2.0 匿名方法
        TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };

        
// C# 3.0 Lambda表达式 委托的用法 , 参数x的类型由编译器推断
        TestDelegate testDelC = (x) => { Console.WriteLine(x); };

        
// 调用委托
        testdelA("Delegate A");
        testDelB(
"Delegate B");
        testDelC(
"Delegate C");
        
        
        Console.ReadKey();
    }
 
}




Lamdba 表达式:

“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。
      delegate int del(int i);
      
static void Main()
      
{
          del myDelegate 
= x => x * x;    // x => x * x 就是 Lamdba 表达式
          int j = myDelegate(5); 

          Console.WriteLine(j.ToString()); 
// 这里输出的是 25

          Console.ReadKey();
      }

      这里的是Lamdba 表达式的委托用法。
      其中符号 "=>" 就是 Lambda 运算符 , 读作“goes to”。
      这运算符的左边包含的是输入的参数 , 右边包含表达式或语句块。
      
      用Reflector可以发现, Lamdba 表达式在编译的时候被解析掉的。
      // 原语句: delegate int del(int i);
      [CompilerGenerated]
      
private static del CS$<>9__CachedAnonymousMethodDelegate1;

      
      
// 原语句: del myDelegate = x => x * x;
      if (CS$<>9__CachedAnonymousMethodDelegate1 == null)
      
{
          CS$
<>9__CachedAnonymousMethodDelegate1 = delegate (int x) {
              
return x * x;
          }
;
      }

      del myDelegate 
= CS$<>9__CachedAnonymousMethodDelegate1;

      也就是说. Lamdba 表达式的委托其实就是 匿名方法 。 
      
      Lamdba 的表达式目录树类型使用:
      static void Main()
      
{
      
          
int[] scores = 907182937582 };
          
          
int highScoreCount = scores.Where(n => n > 80).Count();

          Console.WriteLine(
"{0} scores are greater than 80", highScoreCount);

          
// Outputs: 4 scores are greater than 80            
      }


Lambda 语句:
        Lambda 语句与 Lambda 表达式类似,只是语句括在大括号中,Lambda 语句的主体可以包含任意数量的语句。
        delegate int del(int i);

        
static void Main()
        
{
            del myDelegate 
= (x) => { x++ ;return x * x; };
            
int j = myDelegate(5);

            Console.WriteLine(j.ToString()); 
// 这里输出的是 36

            Console.ReadKey();
        }


Lambda 表达式的一般规则:
Lambda 包含的参数数量必须与委托类型包含的参数数量相同。
Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。
Lambda 的返回值(如果有)必须能够隐式转换为委托的返回类型。
 
Lambda 表达式中的变量规则:
捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止。
在外部方法中看不到 Lambda 表达式内引入的变量。
Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
Lambda 表达式中的返回语句不会导致封闭方法返回。
Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。


  扩展方法:
 
扩展方法必须在一个静态的类里添加:
    static class 扩展方法类
    
{
        
public static string HelloWorld(this string str)
        
{
            
return string.Format("HelloWorld {0}", str);
        }

    }

调用方法:
        static void Main()
        
{
            
string A = "123";
            Console.WriteLine(A.HelloWorld());
            Console.Read();
        }