首页 > 代码库 > C # 开发 —— 拉姆表达式

C # 开发 —— 拉姆表达式

What‘s LINQ? Language Integrated Query 是也。说得再明白一些,这是编程语言的一种新特性,能够将数据查询语句集成到编程语言中。

主要还是因为现在的数据格式越来越多,数据库、XML、数组、哈希表……每一种都有自己操作数据的方式,学起来费事费力。于是,就有了LINQ诞生的理由——以一种统一的方式操作各种数据源,减少数据访问的复杂性。

通过GetMethods的方法,拿到string的所有方法,接下来,选出所有非静态的方法签名

MethodInfo[] methods=typeof(string).getMethods();

var result = from m in methods

where m.IsStatic!=true

select m.Name;

foreach(var r in result)

{  Console.WriteLine(r.ToString()); }

Console.ReadLine();

看起来,var 有点像javascript 里面的弱类型的变量声明。但是,C#是强类型的,尽管你用var来声明,编译器还是可以根据上下文推倒出它当前的类型。

var result =(from m in methods    where m.IsStatic!=true    select m.Name).Distinct();

去掉重复记录


class MyClass{    public string MethodName{get;set;}    public int Overload{get;set;}}class Program{    MyClass mc=new MyClass{MethodName = "aaa",Overload=2};}

大括号里面的叫类初始化器,省去了构造函数,在new的同时,给对象的属性赋值。

var result = from m in methods 
where m.IsStatic != true 
group m by m.Name into g 
select new { MethodName = g.Key, Overload = g.Count() };

 

new一个新对象,居然连类名都不写。没错,这就叫匿名类。


C # 3.0 的新特性

隐含类型局部变量

var age = 26;  var username = "zhuye";  var userlist = new [] {"a","b","c"};  foreach(var user in userlist)  Console.WriteLine(user);

让编译器自己推断变量类型,但是既然让编译器推断类型就必须声明的时候赋值,而且不能是null值。注意,这只能用于局部变量,用于字段是不可以的。

var data = http://www.mamicode.com/new {username = "zhuye",age = 26}; 

Console.WriteLine("username:{0} age:{1}", data.username, data.age);


  匿名类型允许开发人员定义行内类型,无须显式定义类型。常和var配合使用,var用于声明匿名类型。

扩展方法

public static class helper  {     public static string MD5Hash(this string s)      {         return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s,"MD5");     }     public static bool In(this object o, IEnumerable b)      {         foreach(object obj in b)          {             if(obj==o)                 return true;          }         return false;      } } // 调用扩展方法Console.WriteLine("123456".MD5Hash()); Console.WriteLine("1".In(new[]{"1","2","3"}));

对象初始化器

public class Person  { public string username { get; set; }  public int age { get; set; }  public override string ToString()  { return string.Format("username:{0} age:{1}", this.username, this.age);  } } Person p = new Person() {username = "zhuye", age=26};  Console.WriteLine(p.ToString());

编译器会自动为你做setter操作,使得原本几行的属性赋值操作能在一行中完成。这里需要注意:
?    允许只给一部分属性赋值,包括internal访问级别
?    可以结合构造函数一起使用,并且构造函数初始化先于对象初始化器执行

 

集合初始化器

public class Person  { public string username { get; set; }  public int age { get; set; }  public override string ToString()  { return string.Format("username:{0} age:{1}", this.username, this.age);  } } var persons = new List {  new Person {username = "a", age=1},  new Person {username = "b", age=2}};  foreach(var p in persons)  Console.WriteLine(p.ToString());

 

Lambda表达式

var list = new [] { "aa", "bb", "ac" };  var result = Array.FindAll(list, s => (s.IndexOf("a") > -1));  foreach (var v in result)  Console.WriteLine(v);

语法如下:
(参数列表) => 表达式或者语句块

参数个数:可以有多个参数,一个参数,或者无参数。
  表达式或者语句块:这部分就是我们平常写函数的实现部分(函数体)

 

var persons = new List {      new Person {username = "a", age=19},      new Person {username = "b", age=20},      new Person {username = "a", age=21},  }; var selectperson = from p in persons where p.age >= 20 select p.username.ToUpper(); foreach(var p in selectperson)      Console.WriteLine(p);

上面的查询句法等价于下面的代码:

var selectperson = persons.Where(p=>p.age>=20).Select(p=>p.username.ToUpper());

之后的拉姆表达式的功能大部分集中在实体与数据库表项的操作,也就是各种DB操作,先不涉及了~~


Expression<Func<string, bool >> expr = o => o.Length > 10;

初次接触Linq Lambda表达式的人可能会被搞迷糊,这样的语句到底是什么意思,怎么样工作,原理又是什么。

逐级分析以上语句,分为两个部分,以等号为界。

第一部分是变量类型的申明:Expression<Func<string, bool>> expr,表示expr这个变量是一个Linq Lambda表达式,这个表达式符合这样的一种委托:bool DelegateName(string obj)。

第二部分是表达式的声明o => o.Length > 10,这个“=>”是Lambda操作符,读作“转到”,必须把=>左右看成是一个整体,因为这实际是一个匿名方法,“=>”左边是方法传入参数的申明,右边是函数体,如果用常规的表示方法,可以写成如下形式:

bool MethodName(string o)
   {
     return o.Length > 10;
   }

仔细观察两部分拆解以后的形式其实不难发现,第一部分的工作是定义了一个匿名的委托,而第二部分则是符合这个匿名委托的一个方法,由于这个方法没有明确给定名称,因此称为匿名方法。