1.对象初始化器

  1. class Curry
  2. {
  3. public string MainIngredient{get;set;}
  4. public string Style { get; set; }
  5. public int Speciness { get; set; }
  6. }

假如有如上一个类,当我们创建这个类的对象之后需要分别给每个属性赋值

  1. Curry curry=new Curry();
  2. curry.MainIngredient = "painr tikka";
  3. curry.Style = "jal";
  4. curry.Speciness = ;

这样显得非常麻烦,使用对象初始化器可以简化对象创建和初始化的过程。这段代码会调用默认的构造函数创建对象,对象创建之后在给对象属性赋值。也可以在new之后指定使用的构造函数

  1. Curry test = new Curry { MainIngredient = "painr tikka", Style = "jal", Speciness = };
  1. class Curry
  2. {
  3. public string MainIngredient{get;set;}
  4. public string Style { get; set; }
  5. public int Speciness { get; set; }
  6.  
  7. public Curry()
  8. { }
  9.  
  10. public Curry(int speciness)
  11. {
  12. Speciness = speciness;
  13. }
  14. }
  15.  
  16. Curry test = new Curry() { MainIngredient = "painr tikka", Style = "jal"};

 2.集合初始化器

  1. List<int> primes = new List<int>() { , , , , };

集合初始化器会默认调用集合的Add方法来初始化集合,如果集合没有改方法将报错。

3.var关键字

C#3.0引入新的关键字var,允许使用var关键字定义需要编译器辅助确认类型的变量。它并不是创建没有类型或者类型可以变的变量。使用var需要注意:

1)使用var定义的变量声明和初始化必须一起,不能分开,比如var a ; a=0是错误的,正确的是var a =0;

2) var只能定义局部变量,不能定义全局变量;

3)变量初始化之后变量的类型就固定了,不能再用别的类型赋值。

可以使用var声明数组,比如var array =new []{4,5,6},但是数组初始化器的数据必须满足以下条件之一:

1)相同的类型;

2)相同的引用类型或null;

3)所有元素的类型都可以隐式的转换为一种类型。

 4.匿名类型

为了显示数据,我们经常需要建一些简单的类,这些类只有简单的的几个属性,而且如果数据改变了又要更新这个类,最不爽的是这个类仅仅在某个地方用了一下下。比如如下一个类

  1. class Curry
  2. {
  3. public string MainIngredient { get; set; }
  4. public string Style { get; set; }
  5. public int Spicinesss { get; set; }
  6. }

不想建数据类型,匿名类型可以帮我们动态建立一个类型,它会根据我们初始化的数据建立类型。比如如下代码建立了一个匿名类型

  1. var curry = new {
  2. MainIngredient = "Lamb",
  3. Style="Dhansak",
  4. Spicinesss=
  5. };

匿名类型的特征是new后面没有数据类型,这也是编译器确定匿名类型的方式。因为匿名类型没有类型名称,所以只能在当前代码块中使用创建的匿名类型

匿名类型与Equals、GetHashCode、==

  1. class Curry
  2. {
  3. public string MainIngredient { get; set; }
  4. public string Style { get; set; }
  5. public int Spicinesss { get; set; }
  6. }
  7.  
  8. class Program
  9. {
  10.  
  11. static void Main(string[] args)
  12. {
  13. try
  14. {
  15. var curries = new[]{
  16. new {
  17. MainIngredient = "Lamb",
  18. Style="Dhansak",
  19. Spicinesss=
  20. },
  21. new {
  22. MainIngredient = "Lamb",
  23. Style="Dhansak",
  24. Spicinesss=
  25. },
  26. new {
  27. MainIngredient = "Chicken",
  28. Style="Dhansak",
  29. Spicinesss=
  30. }
  31. };
  32.  
  33. Console.WriteLine(curries[].Equals(curries[]));
  34. Console.WriteLine(curries[].Equals(curries[]));
  35. Console.WriteLine(curries[].GetHashCode());
  36. Console.WriteLine(curries[].GetHashCode());
  37. Console.WriteLine(curries[].GetHashCode());
  38. Console.WriteLine(curries[] == curries[]);
  39. Console.WriteLine(curries[] == curries[]);
  40.  
  41. }
  42. catch (RuntimeBinderException ex)
  43. {
  44. Console.WriteLine(ex.Message);
  45. }
  46.  
  47. Console.ReadLine();
  48. }
  49. }

通过以上代码发现匿名类型使用Equals方法时比较的是它们的值是否相等,而不是比较引用;

GetHashCode因为curries[0]、curries[1]两个对象的值相同,所以它们的状态相同,返回的值也就相同。

==比较的是两个对象的引用curries[0]、curries[1]属于两个不同对象,引用不同。

5.动态查找

C#4.0引入了动态变量,动态变量顾名思义就算类型可变的变量。引入动态变量的目的在于使用C#处理另一种语言创建的对象,包括与旧及时今日交互,比如Component Object Model(Com),以及处理JavaScript、ruby、python等动态语言。

比如代码从JavaScript中获取一个Add()方法,该方法把两个参数加在一起。如果没有动态查找功能就需要这样访问Add()方法

  1. ScriptObject jsObj = SomeMethodGetTheObject();
  2. int sum=Convert.ToInt32(jsObj.Invoke("Add", , ));

如果使用动态查找就可以直接调用方法

  1. ScriptObject jsObj = SomeMethodGetTheObject();
  2. int sum=Convert.ToInt32(jsObj.Add(, ));

动态查找方法可以根据变量的具体类型,动态的查找该类型是否有Add方法,如果没有该方法会引发一个RuntimeBinderException异常。

如下是一个使用动态查找的例子

  1. namespace ConsoleApplication1
  2. {
  3. class Program
  4. {
  5.  
  6. static void Main(string[] args)
  7. {
  8. try
  9. {
  10. dynamic firstResult = GetValue();
  11. dynamic secondResult = GetValue();
  12.  
  13. Console.WriteLine("firstResult is :" + firstResult.ToString());
  14. Console.WriteLine("secondResult is :" + secondResult.ToString());
  15. Console.WriteLine("firstResult call :" + firstResult.Add(, ));
  16. Console.WriteLine("secondResult call :" + secondResult.Add(, ));
  17.  
  18. }
  19. catch (RuntimeBinderException ex)
  20. {
  21. Console.WriteLine(ex.Message);
  22. }
  23.  
  24. Console.ReadLine();
  25. }
  26.  
  27. static int callCount = ;
  28. static dynamic GetValue()
  29. {
  30. if (callCount++ == )
  31. return new MyClass1();
  32. return new MyClass2();
  33. }
  34. }
  35.  
  36. class MyClass1
  37. {
  38. public int Add(int op1, int op2)
  39. {
  40. return op1 + op2;
  41. }
  42. }
  43.  
  44. class MyClass2
  45. {
  46.  
  47. }
  48.  
  49. }

 6.高级方法参数:可选参数和命名参数

可选参数

假如一个方法有大量的参数,有些参数并不是每次调用都需要传过去的,这意味着需要一种方式指定缺失的参数,否则在代码中会出现许多空值,比如

  1. RmoteCall(var1,var2,null,null,null,null,null)

在理想情况下,这个RmoteCall方法应该有多个重载版本,其中一个有两个参数,但这样就需要维护更多的代码。

  1. RmoteCall(var1,var2)

使用可选参数可以解决这个问题,可选参数的定义方式是在方法定义时,在参数后面赋默认值

  1. public List<string>GetWords(string sentence,bool capitalizeWords=false)
  2. {
  3. //....
  4. }

可选参数必须放在参数列表末尾,在所有必选参数后面

命名参数

假如有几个可选参数,我们只想给其中一个可选参数赋值,就可以用到命名参数,在调用方法时,指定参数的名和对应的值

  1. public List<string>GetWords(string sentence,bool capitalizeWords=false, bool var1 =false)
  2. {
  3. //....
  4. }
  5.  
  6. //给最后一个可选参数赋值
  7. GetWords("....",var1:true);

 7.扩展方法

我们知道类型的操作是封装在数据类型里面的,使用扩展方法可以扩展类型的功能,而不修改类型本身。

创建一个扩展方法需要以下步骤:

1)创建一个非泛型静态类;

2)创建一个静态方法,该方法必须包含一个参数,该参数放在所有参数前面,用this关键字和类型符修饰,表示调用扩展方法的类型实例;

3)在使用扩展方法的地方用using语句导入包含扩展方法的类的名称空间;

4)通过扩展类型的一个实例调用方法,与调用该扩展类型的其他方法一样。

下面是给string类添加扩展方法的一个例子

  1. namespace ConsoleApplication1
  2. {
  3. static class WordProgressor
  4. {
  5. public static List<string> GetWords(this string sentence, bool capitalizeWords = false, bool reverseOrder = false, bool reverseWords=false)//扩展方法
  6. {
  7. List<string> words = new List<string>(sentence.Split(' '));
  8. if (capitalizeWords)
  9. words = CapitalizeWords(words);
  10. if (reverseOrder)
  11. words = ReverseOrder(words);
  12. if (reverseWords)
  13. words = ReverseWords(words);
  14. return words;
  15. }
  16.  
  17. public static List<string> CapitalizeWords(List<string> words)
  18. {
  19. List<string> capititalzieWords = new List<string>();
  20. foreach (string word in words)
  21. {
  22. if (word.Length == )
  23. capititalzieWords.Add(word[].ToString().ToUpper() );
  24. else if(word.Length >)
  25. capititalzieWords.Add(word[].ToString().ToUpper() + word.Substring());
  26. }
  27.  
  28. return capititalzieWords;
  29. }
  30.  
  31. public static List<string> ReverseOrder(List<string> words)
  32. {
  33. List<string> reverseOrder = new List<string>();
  34. for (int i = words.Count - ; i >= ; i--)
  35. {
  36. reverseOrder.Add(words[i]);
  37. }
  38.  
  39. return reverseOrder;
  40. }
  41.  
  42. public static List<string> ReverseWords(List<string> words)
  43. {
  44. List<string> reverseWords = new List<string>();
  45. foreach (string word in words)
  46. {
  47. reverseWords.Add(ReverseWord(word));
  48. }
  49. return reverseWords;
  50. }
  51.  
  52. public static string ReverseWord(string word)
  53. {
  54. StringBuilder sb = new StringBuilder();
  55. for (int i = word.Length - ; i >= ; i--)
  56. {
  57. sb.Append(word[i]);
  58. }
  59. return sb.ToString();
  60. }
  61.  
  62. public static string ToStringReversed(this Object inputObject)//扩展方法
  63. {
  64. return ReverseWord(inputObject.ToString());
  65. }
  66.  
  67. public static string AsSentence(this List<string> words)//扩展方法,该方法扩展的类型是List<string>,所以只有该类型才能调用
  68. {
  69. StringBuilder sb = new StringBuilder();
  70. for (int i = ; i < words.Count; i++)
  71. {
  72. sb.Append(words[i]);
  73. if (i != words.Count - )
  74. sb.Append(' ');
  75. }
  76. return sb.ToString();
  77. }
  78. }
  79.  
  80. class Program
  81. {
  82.  
  83. static void Main(string[] args)
  84. {
  85. string sourceString = "To go beyond is a wrong as to fall short.";
  86.  
  87. Console.WriteLine(sourceString.ToStringReversed());
  88. Console.WriteLine(sourceString.GetWords(capitalizeWords: true).AsSentence());
  89. Console.ReadLine();
  90. }
  91.  
  92. }
  93.  
  94. }

23.C# 语言的改进的更多相关文章

  1. GO学习-(23) Go语言操作MySQL + 强大的sqlx

    Go语言操作MySQL MySQL是业界常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库. Go操作MySQL 连接 Go语言中的database/sql包提供了保证SQL或类SQL数据 ...

  2. 2-3 R语言基础 矩阵和数组

    #矩阵Matrix  三个参数:内容(可省),行数,列数 > x <- matrix(1:6,nrow = 3,ncol = 2) #第一个是内容,第二个,第三个是行列> x[1,2 ...

  3. Rust 2017 调查报告:学习曲线是最大痛点(最大的问题是这门语言太偏底层了,现在做底层的少了。还有C这个绕不过去的存在)

    Rust 官方在社区上做了一次调查,以了解用户如何看待 Rust 的发展.调查共收到 5368 份回复,其中有 大约 2/3 的是 Rust 用户,剩下的 1/3 是非 Rust 用户,调查结果如下. ...

  4. 【GoLang】转载:我为什么放弃Go语言,哈哈

    我为什么放弃Go语言 作者:庄晓立(Liigo) 日期:2014年3月 原创链接:http://blog.csdn.NET/liigo/article/details/23699459 转载请注明出处 ...

  5. C语言不是C++的严格子集

    C语言是C++的子集吗?C++是在C语言的基础上扩展而来并包含所有C语言的内容吗? 回复: 从实用角度讲,C++属于C语言的一个超集,基本上兼容ANSI C.但是从编译角度上讲,C语言的有些特性在C+ ...

  6. 我为什么放弃Go语言

    有好几次,当我想起来的时候,总是会问自己:我为什么要放弃Go语言?这个决定是正确的吗?是明智和理性的吗?事实上我一直在认真思考这个问题. 开门见山地说,我当初放弃Go语言(golang),就是由于两个 ...

  7. c语言,变长数组

    下面这个结构体,可以在malloc的时候指定数据data的长度,这样的形式就是变长数组:typedef struct{ int data_len; char data[0];//或char data[ ...

  8. java语言与jvm虚拟机简介

    一.java语言 1.1 支持面向对象编程oop 强调支持,因为java同样可以面向过程编程. oop的三大特性是:封装.继承.多态. 封装主要针对成员变量而言,oop的思想要求成员变量均为私有,不应 ...

  9. 驳2B文 "我为什么放弃Go语言"

      此篇文章流传甚广, 其实里面没啥干货, 而且里面很多观点是有问题的. 这个文章在 golang-china 很早就讨论过了. 最近因为 Rust 1.0 和 1.1 的发布, 导致这个文章又出来毒 ...

随机推荐

  1. Python_多进程

    Python 多进程库 multiprocessing ,支持子进程.通信.数据共享.执行不同形式的同步 多进程,绕过gil ,实现多核的利用,多进程也是原生进程,由操作系统维护 在pycharm中, ...

  2. linux(CentOS)磁盘挂载数据盘

    linux(CentOS)磁盘挂载数据盘:第一步:查看是否存在需要挂载的磁盘: sudo fdisk -l 第二步:为需要挂载的磁盘创建分区: sudo fdisk /dev/vdb 执行中:依次选择 ...

  3. python实现FTP程序

    python实现FTP程序 程序源码 上传功能 查看文件 cd功能 创建目录 程序源码 目录结构 服务端 主程序 import optparse import socketserver import ...

  4. Numpy初步

    1,获取矩阵行列数 Import numpyasnp #创建二维的naaray对象 a=np.array([[1,2,3,4,5],[6,7,8,9,10]]) print(a.shape)   #返 ...

  5. c++模板文件,方便调试与运行时间的观察

    #define _CRT_SECURE_NO_WARNINGS#include<iostream>#include <vector>#include<algorithm& ...

  6. VS2013安装Boost

    boost的编译和使用,经过搜集资料和总结,记录成文.感谢文后所列参考资料的作者. 1 下载 地址:http://sourceforge.net/projects/boost/files/boost/ ...

  7. __x__(25)0907第四天__ overflow 父元素对溢出内容的处理

    overflow    父元素对于溢出内容的处理 visible;    默认值,对于溢出内容,在父元素之外显示. hidden;    对于溢出内容,进行隐藏,不显示. scroll;    对于溢 ...

  8. thinkphp实现like模糊查询实例

    原网址:https://www.jb51.net/article/56846.htm

  9. 第二天(就业班) html的引入、html常用标签、实体标签、超链接标签、图片标签、表格、框架标签、表单[申明:来源于网络]

    第二天(就业班) html的引入.html常用标签.实体标签.超链接标签.图片标签.表格.框架标签.表单[申明:来源于网络] 第二天(就业班) html的引入.html常用标签.实体标签.超链接标签. ...

  10. 洛谷P1115 最大字段和【线性dp】

    题目:https://www.luogu.org/problemnew/show/P1115 题意: 求给定数组的最大区间和. 思路: $dp[i][0]$表示以1~i的数组,不选i的最大字段和.$d ...