`
gaofen100
  • 浏览: 1227608 次
文章分类
社区版块
存档分类
最新评论

尝尝C#的语法糖(自动属性/匿名方法/Lamda表达式等)-小心蛀牙!

 
阅读更多

语法糖意指那些没有给计算机语言添加新功能,而只是对人类来说更“sweet”的语法,意在使得编程风格更易读。C#2.0,3.0发布的新特性,除了泛型不是语法糖,其他所有的新特性几乎都是语法糖。

-但初学者往往因为不了解这些语法糖,从而在阅读代码的时候,难以理解其真正的运作方式。最著名的莫过于Lamda表达式,第一次看到它,很多人都会顶个大问号把。。。

-文章前面会伴随一些让人看着想吐槽的代码,请大家自行河蟹。然后我们会介绍一些语法糖来润色一下,方便初学者们知道这些语法糖的原始意义。

  我们来做一个List<T>类的练习。我会写一个很蛋疼的例子(尽量不用语法糖,当然这很难避免)。首先我定义了一个学生类

public class Student
{
    private string num;
    public string Num { get { return num; } }
    private string name;
    public string Name { get { return Name; } }
    public Student(string num, string name)
    {
        this.num = num;
        this.name = name;
    }
    public override string ToString()
    {
        return num + ":" + name;
    }
}

  现在练习下List<T>的FindAll()方法,它的声明如下

public T FindAll(Predicate<T>match)

  FindAll方法把Predicate<T>作为参数,Predicate<T>是一个委托,它引用一个谓词方法-返回布尔值的方法。如果谓词返回true,表示有一个匹配。

  所以我写了一个FindStudent类来定义谓词。这个方法用要搜索的学生的学号来初始化,FindPredicate()接收一个student对象,比较student对象的学号与构造函数中设置的学号,返回true or false。

 public class FindStudent
    {
        private string num;
        public FindStudent(string num)
        {
            this.num = num;
        }
        public bool FindPredicate(Student student)
        {
            return student.Name== Name;
        }
    }

  最后在一个控制台程序里搜索名字叫John的学生。

  class Program
    {
        static void Main(string[] args)
        {
            List<Student> Students = new List<Student>();
            Students.Add(new Student("001", "John"));
            Students.Add(new Student("002", "Marry"));
            Students.Add(new Student("003", "John"));
            FindStudent finder = new FindStudent("John");
            foreach (var student in Students.FindAll(new Predicate<Student>(finder.FindPredicate)))
            {
                Console.Write(student);
            }
        }
    }

  有没有人看到这已经扛不住了呢,特别是对FindStudent类和FindAll的冗长的用法?

  下面我们来一点一点的润色把。

  甜死你1号-自动属性:只需在定义一个类时指定属性名,C#3.0编译器将自动实现相应的内部的private变量,并自动生成set访问器和get访问器。

  甜死你2号-对象初始值设定项:在自动属性的前提下,在创建对象时可以对任何可访问的属性或字段赋值,而不需要显示的调用构造函数。

  基于这两个特性,我们来修改一下Student类:

public class Student
{
    public string Num { get; set; }

    public string Name { get;set; }

    public override string ToString()
    {
        return Num + ":" + Name;
    }
}

 

  自动属性会自动生成私有变量,不需要显示的声明,并且可以直接通过对象初始值设定项对可访问的属性和字段赋值,构造函数也不是必须的。呃,是不是清爽多了。

  甜死你3号-匿名方法 : 我们之前必须首先声明方法后才能在委托中使用,C#2.0引入匿名方法,可以delegate{ //dosomething}的形式以一种“内联”的方式来编写方法代码,将代码直接与委托实例相关联,从而使得委托实例化的工作更加直观和方便。

  有些时候我们需要临时保存一些运算的中间结果,我们常常会去声明一个新的类型,以方便保存这些中间结果。表面上 看起来这很正常,而细想之后就会发现,这个新类型只服务于这个函数,其它地方都不会再使用它了,就为这一个函数而去定义一个新的类型,确实有些麻烦,比如FindStudent类。

  有了匿名方法FindStudent类已经没有存在的意义了(大快人心?),因为自动属性的关系,我们可以直接访问属性,并且用匿名方法来代替谓词。

  插播广告:

  甜死你4号-集合初始值设定项:我们除了可以像初始化数组一样,初始化对象之外,同样对于集合也可以不用再重复的Add来增加集合项了,我们来看新的Main函数:

    static void Main(string[] args)
        {
            List<Student> Students = new List<Student>()
            {
             new Student(){ Num="001", Name="John"},//使用对象初始值设定项初始化对象,代替构造函数
             new Student(){ Num="002", Name="Marry"},
             new Student(){ Num="003", Name="John"}
            };//使用集合初始值设定项初始化集合,不用重复调用Add方法
            foreach (var student in Students.FindAll(delegate(Student student) { return student.Name == "John"; }))//使用匿名方法完成FindStudent类的功能
            {
                Console.WriteLine(student);
            }
            Console.ReadKey();
        }

  是不是看着顺眼多了。不过foreach这句还是有点不顺眼。肿么办,我们只好开大招了。

  甜死你终结者号-Lamda表达式:它是升级版的匿名方法,其作用是简化匿名方法的写法。写法(形参列表)=>{函数体}

  delegate(Student student) { return student.Name == "John"; }这个匿名方法为例,我们的参数就只有student一个,形参我们就使用s代替。

  Lamda表达式就是 s=>s.Name=="John"。

  顺便我们用一下List<T>的ForEach方法。

  又一条广告: 

  甜死你路人号-匿名类型: 使用var关键字来进行类型声明,而不需要显示的声明类型,具体的类型将由编译器来推断。

  最终的Main函数就是:

   static void Main(string[] args)
        {
            List<Student> Students = new List<Student>()
            {
             new Student(){ Num="001", Name="John"},//使用对象初始值设定项初始化对象,代替构造函数
             new Student(){ Num="002", Name="Marry"},
             new Student(){ Num="003", Name="John"}
            };//使用集合初始值设定项初始化集合,不用重复调用Add方法
            var John = Students.FindAll(s => s.Name == "John");//使用var声明匿名类型,其实John是个List<Student>
            John.ForEach(j => Console.WriteLine(j));//使用Lamda表达式
            Console.ReadKey();
        }

  这样的代码看着就很舒服了。

  当然语法糖还有很多,如文章开头所说,C#的新特性大多是语法糖。当然还有一些其他的语法糖,比如三元运算符Test?expression1:expression2就有一个语法糖,写作

  expression1??expression2   2选1,expression1为null则执行expression2。反之执行expression1。

  欢迎大家补充,这里就不多做介绍了。

  --------------------------------------------我是分割线------------------------------------------------

  语法糖能够增加程序的可读性,但凡事都有两面性。比如你需要在属性的get方法中写一些逻辑,显然自动属性就不适用了。所以不必强求。

  咱别硬吃把牙吃坏了。。。

0
0
分享到:
评论

相关推荐

    委托匿名方法LAMDA表达式

    委托、匿名方法和Lambda表达式是C#编程语言中的核心概念,它们在处理函数式编程和事件处理等方面发挥着重要作用。下面将详细解释这三个概念及其相互关系。 **委托(Delegate)** 委托在C#中是一种类型,它代表了一...

    C# Lamda表达式简单运用

    C# Lamda表达式简单运用

    C#源代码-匿名函数和lamda表达式的写法.zip

    Lambda表达式是C#中匿名函数的一种表现形式,其语法结构为 `(参数列表) =&gt; 表达式` 或 `(参数列表) =&gt; { 函数体 }`。这里的参数列表可以是零个、一个或多个,而表达式或函数体则定义了该匿名函数的行为。例如,一个...

    如何使用Lamda表达式

    Lambda表达式是一种简洁的、内联方式定义函数的方法,常用于创建匿名函数。这种表达式在许多编程语言中都有应用,尤其是在支持面向对象或函数式编程的语言中更为常见。在.NET框架中,尤其是C#语言,Lambda表达式被...

    lamda表达式

    ### Lambda 表达式及其在 C# 中的应用 在 C# 的高级编程中,Lambda 表达式的理解和应用是至关重要的。随着 C# 4.0 的推出,一系列新的编程特性如 LINQ 和 Lambda 表达式等为开发者提供了更多便利和强大的功能。本文...

    lamda-demo-main.zip

    Lambda 是一种事件驱动的服务,它会自动执行代码以响应特定事件,如文件上传、API调用或是数据库更新。这种模式消除了管理和运行基础设施的负担,只需专注于编写和运行代码。 2. **Lambda 函数** 在Lambda中,...

    lamda表达式.rar

    Lambda表达式是一种简洁、轻量级的方式来定义匿名函数,它可以被用作方法参数或者返回值。在本压缩包文件"lamda表达式.rar"中,可能包含有关如何理解和使用C# Lambda表达式的详细教程或示例代码。 Lambda表达式的...

    C#将Lambda表达式转成Sql语句

    2. **解析表达式树**:通过递归遍历表达式树,我们可以解析出查询操作的细节,如属性访问、条件判断、函数调用等。 3. **构造SQL语句**:根据解析出的信息,我们可以构造对应的SQL语句片段。例如,`Expression....

    学习Java 8【Lamda表达式开发】免费视频

    本课程主要针对于Java 8(JDK 1.8)的新特性Lamda表达式进行了全面讲解。讲解了java基于函数编程的语法,以及与Lamda表达式操作有关的内建接口、批处理、MapReduce数据分析汇总处理。

    全面的Linq语法-SQL语法-lambda表达式对照(相同功能的不同于法)

    在.NET框架中,Language Integrated Query(LINQ)是一种强大的编程技术,它允许开发者使用一致的查询语法在各种数据源上进行操作,包括数据库、集合、XML等。与传统的SQL语句相比,LINQ提供了一种更面向对象的、...

    Java系列JDK 1.8 新特性之 Lambda表达式.pdf

    Lambda表达式本质上是一个匿名函数,能够作为一个参数传递给方法调用或存储在变量中,这使得Java支持了更高层次的函数式编程概念。 Lambda表达式的引入极大地简化了Java代码,使其变得更加简洁和易读。通过使用...

    lamda表达式 part3

    ### Java 8 Lambda 表达式之函数式接口详解 #### 一、引言 Java 8 的引入带来了一系列重大的变化,其中 Lambda 表达式作为最具革命性的特性之一,极大地简化了代码编写,提高了程序的可读性和可维护性。在前两篇...

    lamda 优美表达式 可作为仿照的案例demo

    在Java 8中,很多接口都添加了默认方法(default methods),如`java.util.Function`、`java.util.Consumer`、`java.util.Predicate`等,这些接口与Lambda表达式相结合,使得函数式编程变得更加直观。例如,`...

    jdk-8公司内网下载

    2. 函数式接口:这些接口有一个抽象方法,可以用于lamda表达式的类型安全。 3. 方法引用和构造器引用:它们允许直接引用类的静态方法和构造器,而不必创建匿名类。 4. Stream API:提供了新的集合操作方式,支持数据...

    C++11新特性:Lambda表达式.pdf

    Lambda表达式的语法使用一对方括号作为开始的标识,类似于声明一个函数,只不过这个函数没有名字,也就是一个匿名函数。这个匿名函数接受两个参数,a和b;其返回值是一个bool类型的值,注意,返回值是自动推断的,不...

    jdk1.8 lamda表达式_stream.md

    jdk1.8的特性

    解读ASP.NET 5 & MVC6系列教程(12):基于Lamda表达式的强类型Routing实现

    基于Lamda表达式的强类型Routing,首先需要使用GetRoute或PostRoute等扩展方法来定义具体的路由规则。与传统的字符串模板不同,这种方式通过Lambda表达式来指向控制器类型和动作方法,使得路由与代码间的联系更为...

    Spring_SpEl表达式使用用例

    **Spring SpEL表达式使用详解** Spring Expression Language (SpEL)是Spring框架中的一种强大而灵活的表达式语言,主要用于在运行时查询和操作对象图。它提供了在配置元数据中进行表达式评估的能力,使得我们可以...

Global site tag (gtag.js) - Google Analytics