一. 语法糖简介

    语法糖也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。

需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换;而且可以提高开发编码的效率,在性能上也不会带来损失。

在编译器发展早期,编译器科学家门一直在想方设法的优化编译器生成的代码,这个时候,编译器做的主要是对机器优化,因为那个时候机器的时间非常宝贵,机器运算速度也不快,今天我们有了足够好的机器了(但并不是说我们可以不关注性能的编写程序),而且作为编写软件的人来说,比机器的时间宝贵得多,所以今天的编译器也在向人优化了,从编程语言的发展之路来讲,今天的编程语言比昨天的语言更高级,也更人性化了,我们只要编写更少的代码,更符合人的思维的代码,而只要关注我们值的关注的地方。体力活儿就交给编译器吧。

二. 常用语法糖

1. 自动属性

(1).  传统的方式在类中声明一个属性,需要先声明一个私有变量的字段,然后在配合公有属性,如下面的:userId属性。

(2). 利用自动属性:不需要字段,声明一个空属性,直接get,set(快捷键:prop),编译时编译器为我们生成存取数据的字段. 如下面的:userName属性。

  1. public class userInfor
  2. {
  3. //私有字段
  4. private string _userId;
  5. //公有属性
  6. public string userId
  7. {
  8. get
  9. {
  10. return _userId;
  11. }
  12. set
  13. {
  14. _userId = value;
  15. }
  16. }
  17.  
  18. public string useName { get; set; }
  19.  
  20. /// <summary>
  21. /// 为了后面的反射调用
  22. /// </summary>
  23. public void Test()
  24. {
  25. Console.WriteLine("我是一个方法");
  26. }
  27.  
  28. }

2. var和dynamic

(1). var类型:声明变量的时候可以不指定类型,由编译器编译的时候来指定类型。

  ①:必须在定义的时候初始化

  ②:必须是局部变量

  ③:一旦初始化完成,不能再给变量赋与初始值不同类型的值了,但是可以赋相同类型的不同值.

  ④:var在效率是和使用强类型方式定义变量是一样的

(2). dynamic类型:编译期间不做任何检查,运行期间才确定类型。

  ①:定义的时候可以不必初始化

  ②:可以是全局变量,也可以是局部变量

  dynamic在反射中的应用:通过反射拿到类后,赋值给dynamic类型,该类型的对象可以直接点来调用方法

  缺点:dynamic在运行的时候才进行检测,导致编译的时候即使有错误也不会被发现; 不能用dynamic类型给确定类型的变量进行赋值

  1. public class CompareTwo
  2. {
  3. //2. 可使用的范围
  4. // var b1 = 1; //报错,var必须定义在方法呃逆
  5. // dynamic b2 = 2; //正常
  6. public static void Show()
  7. {
  8. {
  9. //1. 初始化比较
  10. //var a1; //报错,定义的时候必须初始化
  11. //dynamic a2; //正常
  12. }
  13. {
  14. //3. 赋值问题
  15. var c1 = ;
  16. //c1 = "2"; //报错,初始化完成不能赋值不同类型的变量
  17. c1 = ; //正常,初始化完成可以赋值相同类型的变量的不同值
  18.  
  19. dynamic d1 = ;
  20. d1 = ""; //正常,运行时检查进行类型指定,所以在编译的时候不会报错
  21. d1 = ; //正常
  22.  
  23. var userInfor = new userInfor();
  24. userInfor.useName = "";
  25. userInfor.userId = "";
  26. // userInfor.fk123(); //报错,编译不通过
  27.  
  28. dynamic userInfor2 = new userInfor();
  29. userInfor2.userId = "";
  30. userInfor2.useName = "ypf";
  31. //调用不存在的方法 (因为编译的时候根本不检查,所以不会报错,运行的时候报错)
  32. //userInfor2.fk123(); //编译期间不报错,运行的时候报错
  33.  
  34. }
  35. {
  36. //4. dynamic在反射中的应用
  37. //4.1 常规反射调用方法
  38. Type type1 = typeof(userInfor);
  39. object oStudent = Activator.CreateInstance(type1);
  40. MethodInfo method = type1.GetMethod("Test");
  41. method.Invoke(oStudent,null);
  42.  
  43. //4.2 利用dynamic简化调用
  44. //定义和编译的时候可以是任何类型,运行的时候进行转换
  45. dynamic oStudent2 = Activator.CreateInstance(type1);
  46. oStudent2.Test();
  47.  
  48. }
  49. }
  50. }

3. 可选参数

给方法的参数可以指定默认值,如果在调用该方法的时候,不传入该参数,则走默认值,传入的话,则覆盖默认参数.

(1).  有默认值的参数必须定义在没有默认值的参数之后

(2).  默认参数必须是常量,不能是变量

(3).  ref和out参数不能指定默认值

  1. public class OptionalParas
  2. {
  3. public static void Test(string useName,string userPwd,int userAge=,string userSex="男")
  4. {
  5. Console.WriteLine("userName:{0},userPwd:{1},userAge:{2},userSex:{3}", useName, userPwd, userAge, userSex);
  6. }
  7. }
  1.       //3.可选参数
  2. Console.WriteLine("----------------------3.可选参数-------------------------");
  3. OptionalParas.Test("ypf1", "");
  4. OptionalParas.Test("ypf2", "", , "女");

4. 对象(集合)初始化器

  1. public class ObjectInitilize
  2. {
  3. public static void Test()
  4. {
  5.  
  6. //一.对象初始化
  7. //1. 传统初始化对象的方式
  8. userInfor uInfor1 = new userInfor();
  9. uInfor1.userId = "";
  10. uInfor1.useName = "ypf1";
  11.  
  12. //2.对象初始化器
  13. userInfor uInfor2 = new userInfor()
  14. {
  15. userId="",
  16. useName="ypf2"
  17. };
  18. userInfor uInfor3 = new userInfor()
  19. {
  20. userId = "",
  21. useName = "ypf3"
  22. };
  23.  
  24. //二. 集合初始化
  25. //1. 传统方式
  26. List<userInfor> uList = new List<userInfor>();
  27. uList.Add(uInfor1);
  28. uList.Add(uInfor2);
  29.  
  30. //2. 集合初始化器
  31. List<userInfor> uList2 = new List<userInfor>(){
  32. uInfor1,
  33. uInfor2,
  34. new userInfor(){
  35. userId="",
  36. useName="ypf4"
  37. }
  38. };
  39.  
  40. }
  41. }

5. ref和out

二者共同的使用场景,将ref或out参数传入方法中,执行完方法后,可以直接使用ref或out参数值。

  (1). ref必须在使用前赋值,即传入方法前进行定义并赋值

  (2). out必须在方法中赋值然后使用,在调用方法前声明两个未实例化的变量,用来传入和接收使用

举例:有两个int类型的值num1和num2,分别使用ref和out传入对应的方法中,进行值交换。

  1. public class CompareRO
  2. {
  3. /// <summary>
  4. /// ref的使用
  5. /// </summary>
  6. public static void TestRef()
  7. {
  8. int num1 = ;
  9. int num2 = ;
  10. Func1(ref num1, ref num2);
  11. Console.WriteLine("num1的值为:{0},num2的值为:{1}", num1, num2);
  12. }
  13.  
  14. public static void TestOut()
  15. {
  16. int num1;
  17. int num2;
  18. Func2(out num1, out num2);
  19. Console.WriteLine("num1的值为:{0},num2的值为:{1}", num1, num2);
  20. }
  21.  
  22. #region ref版参数值交换
  23. public static void Func1(ref int n1, ref int n2)
  24. {
  25. int a = n1;
  26. n1 = n2;
  27. n2 = a;
  28. }
  29. #endregion
  30.  
  31. #region out版参数值交换
  32. public static void Func2(out int n1,out int n2)
  33. {
  34. n1 = ;
  35. n2 = ;
  36. int a = n1;
  37. n1 = n2;
  38. n2 = a;
  39. }
  40. #endregion
  41.  
  42. }

6. 匿名类/匿名方法

  详见:.Net进阶系列(3)-匿名类、匿名方法、扩展方法

7. 扩展方法

  详见:.Net进阶系列(3)-匿名类、匿名方法、扩展方法

第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)的更多相关文章

  1. C#语法糖之第二篇: 参数默认值和命名参数 对象初始化器与集合初始化器

    今天继续写上一篇文章C#4.0语法糖之第二篇,在开始今天的文章之前感谢各位园友的支持,通过昨天写的文章,今天有很多园友们也提出了文章中的一些不足,再次感谢这些关心我的园友,在以后些文章的过程中不断的完 ...

  2. .NET中那些所谓的新语法之一:自动属性、隐式类型、命名参数与自动初始化器

    开篇:在日常的.NET开发学习中,我们往往会接触到一些较新的语法,它们相对以前的老语法相比,做了很多的改进,简化了很多繁杂的代码格式,也大大减少了我们这些菜鸟码农的代码量.但是,在开心欢乐之余,我们也 ...

  3. C#中的自动属性、隐式类型var、对象初始化器与集合初始化器、扩展方法

    1.自动属性(Auto-Implemented Properties) //以前的写法 .net2.0 private string _userName; public string UserName ...

  4. Linq之隐式类型、自动属性、初始化器、匿名类

    目录 写在前面 系列文章 隐式类型 自动属性 初始化器 匿名类 总结 写在前面 上篇文章是本系列的小插曲,也是在项目中遇到,觉得有必要总结一下,就顺手写在了博客中,也希望能帮到一些朋友.本文将继续介绍 ...

  5. C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询

    1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...

  6. [读书笔记]C#学习笔记五: C#3.0自动属性,匿名属性及扩展方法

    前言 这一章算是看这本书最大的收获了, Lambda表达式让人用着屡试不爽, C#3.0可谓颠覆了我们的代码编写风格. 因为Lambda所需篇幅挺大, 所以先总结C#3.0智能编译器给我们带来的诸多好 ...

  7. [C#详解] (1) 自动属性、初始化器、扩展方法

    文章来源:Slark.NET-博客园 http://www.cnblogs.com/slark/p/CSharp-focus-1.html 代码下载:点我下载 目录 前言 属性与自动属性 属性 自动属 ...

  8. C#学习笔记四: C#3.0自动属性&匿名属性及扩展方法

    前言 这一章算是看这本书最大的收获了, Lambda表达式让人用着屡试不爽, C#3.0可谓颠覆了我们的代码编写风格. 因为Lambda所需篇幅挺大, 所以先总结C#3.0智能编译器给我们带来的诸多好 ...

  9. C#的隐式类型、匿名类型、自动属性、初始化器

    1.隐式类型 1)源起 在隐式类型出现之前,我们声明一个变量时,需要为它指定相应的类型,甚至在foreach一个集合的时候,也要为遍历的集合元素,指定变量的类型,隐式类型出现后,程序员就不用再做这个工 ...

随机推荐

  1. 含有package关键字的java文件在命令行运行报错

    程序中含有package关键字,使用命令行运行程序时出现"找不到或无法加载主类",而使用Eclipse软件可以正常运行程序的可能解决办法. 在包下的类,在Java源文件的地方编译后 ...

  2. RabbitMQ集群搭建和使用

    一.环境准备 1.选择RabbitMQ的版本 http://www.rabbitmq.com/changelog.html 注: 不同版本的Linux选择的RabbitMQ版本也不同,参照 http: ...

  3. springboot中,页面访问不到静态资源

    例一,静态资源放在默认的目录,如:resources/static或resources/templates 访问静态资源的时候,路径不应带上默认目录,因为springboot默认从这些目录下开始加载, ...

  4. Docker(2):使用Dockerfile创建支持SSH服务的镜像

    1.创建工作目录 # mkdir sshd_ubuntu # ls 在其中,创建Dockerfile和run.sh文件 # cd sshd_ubuntu/ # touch Dockerfile run ...

  5. Linux内存管理 (20)最新更新和展望

    专题:Linux内存管理专题 关键词:OOM.swap.HMM.LRU. 本系列没有提到的内容由THP(Transparent Huge Page).memory cgroup.slub.CMA.zr ...

  6. 6-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇-优化升级(安装Apache (Web服务器)软件,测试HTTP)

    为了和SDK升级保持协议一致,花了两天时间实现了用LUA开发,MQTT+HTTP方式实现远程升级 安装Apache主要是为了实现通过HTTP下载资源 升级介绍: 0,用户点击检查更新时,APP首先通过 ...

  7. Pandas 把数据写入csv

    Pandas 把数据写入csv from sklearn import datasets import pandas as pd iris = datasets.load_iris() iris_X ...

  8. cookie跨域共享

    domain和path属性,domain就是当前域,默认为请求的地址,如网址为www.jb51.net/test/test.aspx,那么domain默认为www.jb51.net,path默认就是当 ...

  9. JS 设计模式一 -- 原型模式

    原型模式 概念: 原型模式 是指原型实例指向创建对象的种类,并通过拷贝这些原型创建新的对象,是一种用来创建对象的模式,也就是创建一个对象作为另一个对象的prototype属性. 实现原型模式: 方法一 ...

  10. 安装inotify-tools监控工具

    安装inotify-tools监控工具 yum install -y inotify-tools 2:查看inotify-tools包的工具程序 [root@dns3 ~]# rpm -ql inot ...