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 { get; set; }
public string Name { get; private set; } // 只读
public int CustomerID { get; private set; } // 只读
}
{
public double TotalPurchases { get; set; }
public string Name { get; private set; } // 只读
public int CustomerID { get; private set; } // 只读
}
对象和集合初始值设定项:
通过对象和集合初始值设定项,初始化对象时无需为对象显式调用构造函数。
public class T
{
public int T1 { get; set; } //属性的自动实现
public string T2 { get; set; }
}
static void Main()
{
T NewT = new T { T1 = 10, T2 = "NewT" }; //设定初始值
//
}
{
public int T1 { get; set; } //属性的自动实现
public string T2 { get; set; }
}
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();
}
}
{
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();
}
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;
[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 = { 90, 71, 82, 93, 75, 82 };
int highScoreCount = scores.Where(n => n > 80).Count();
Console.WriteLine("{0} scores are greater than 80", highScoreCount);
// Outputs: 4 scores are greater than 80
}
{
int[] scores = { 90, 71, 82, 93, 75, 82 };
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();
}
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);
}
}
{
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();
}
{
string A = "123";
Console.WriteLine(A.HelloWorld());
Console.Read();
}