最近工作较忙,手上有几个项目等着我独立开发设计,所以平时工作日的时候没有太多时间,下班累了就不想动,也就周末有点时间,今天我花了一个下午的时间来继续总结与整理书中要点,在整理的过程中,发现了书中的一些不足,我在以下的博文中都有说明,大家如果有这本书的可以对照着知识点及书本相结合的方式来看,没有这本本书的也可以对照着我整理的知识要点进行实际编码测试与学习,希望能对大家有所帮助,如果觉得可以的话,还请推荐哦,谢谢!
阅读《LEARNING HARD C#学习笔记》知识点总结与摘要系列文章从这篇博文开始,涉及的知识点的会越来越深入,希望大家能受益,若发现有不足之处,还请指出,谢谢!
首先补充之前的一个知识点:
委托只能定义在命名空间、类中,而不能定义在方法中(即:不能局部定义),这个在书中没有说明,我是在写代码的时候认识到的,也请大家测试一下,看能否找出根本原因。
经我测试,发现不只委托类型,所有的自定义类型均不能在方法体中定义,均报错,关于这个问题的思考与分析详见我的博文:
C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)
十三.泛型可变性
协变:指泛型类型参数可以从一个派生类隐式地转换为基类,用out关键字标识类型参数,以标明其支持协变性。(即:可将子类型的类型参数泛型对象赋值给父类型的类型参数泛型对象),如:
List<object> objectList=new List<object>();
List<string> stringList=new List<string>();
objectList.AddRange(stringList);
逆变:指泛型类型参数可以从一个基类隐式的转换为派生类,用in关键字标识类型参数,以标明其支持逆变性。(即:可将父类型的类型参数泛型对象赋值给子类型的类型参数泛型对象)。
逆变与协变刚好相反,可以理解协变是泛型类型参数的子类替换为父类的过程,逆变是泛型类型参数的父类替换子类的过程。
注意:
十四.可空类型
Int? nullInt=null; nullInt= nullInt??0; nullInt的最终值是0;
十五.匿名方法
委托类型 anonymousMethod=delegate(形参列表)
{
//方法主体
};
十六.迭代器
1.foreach循环原理是,通过访问迭代器(IEumerator),然后不断的获取下一个对象(MoveNext、Current),直到找不到下一个对象为止才停止循环。一个对象若需使用foreach循环,则该对象的类型必须实现IEumerable或IEumerable<T>接口,同时必须实现GetEnumerator方法来返回迭代器。
2. 实现GetEnumerator方法可能通过yield return 关键字来动态生成迭代器(迭代器的生成由编译器来完成)
十七.C#3.0新特性
类的属性简化定义(自动实现属性):访问修饰符类型 属性名{get;set;},无需声明私有变量来存放属性的值,编译器在编译的时候会自动生成。
隐式类型:采用var关键字来取代定义变量的类型(类似Javascript的var),变量的实际类型等于其值的类型,因为隐式类型需要依据变量的值来得出其真实类型,所以定义隐式类型的变量同时必须进行变量初始化,未初始化的或其初始化的值无法直接获得实际类型的(比如:NULL)将会报错。
注意隐式类型(var)仅能声明在局部变量中,不能声明为类的成员类型(字段、属性、方法)以及方法的形参类型
隐式数组:实例化数组时无需指定数组的类型及个数,直接赋值数组各成员(利用的是集合初始化器),但需注意数组成员的类型必须统一,否则无法获得真实类型,也就不满足隐式类型的定义要求,会报错的。定义语法如下:
Var intArray=new[]{1,2,3,4,5,6,7,8,9,10};
对象初始化器:在通过new调用类型的构造函数的同时(任意一个可实例的公共构造函数,未限定为无参的构造函数),直接赋值各类型的成员,定义语法如下:
类型 变量名=new 类型(参数){ 属性=值,… …};
例子:Person p=new Person(){Name=”zuowenjun”,Age=29}; Person p=new Person(“zuowenjun”){ Age=29,Sex=”男”};
集合初始化器:在通过new调用类型的构造函数的同时(任意一个可实例的公共构造函数,未限定为无参的构造函数),直接赋值各类型的成员,但需要注意的是必需实现Add方法,编译器是通过自动调用Add方法来实现集合的添加的。
定义语法如下:
类型 变量名=new 类型(参数){成员对象,… …};
例子:
List< Person> personList=new List< Person>(){new Person{Name=“张三”,Age=10}, new Person{Name=“李四”,Age=20}};
String[] strs=new[]{“a”,”b”,”c”,”d”};
Dictionary<int, string> dic = new Dictionary<int, string>(4) { { 1, "a" }, { 2, "b" }, { 3, "c" }, { 4, "d" } };
匿名类型:即无需定义类型,通过隐式类型和对象初始化器两种特性来实例化一个未知类型的对象,定义语法如下:
Var 变量名=new{属性名=值};
注意:匿名类型的访问范围默认为Internal且不可更改,只能进行属性成员赋值,不能定义除属性外的其它成员(事件,索引器等),且属性成员不能添加访问修饰符默认为公共,属性的类型就是其值的实际类型,属性值的类型不限。
例子:
Func<string,string> sayFunc=delegate(string yourname){return yourname + ",您好。很高兴认识你!";};
var Person = new { Name = "zuowenjun", Age = 29, Sex = "男", WebSite = "www.zuowenjun.cn", Say = sayFunc};
Console.WriteLine(Person.Say("博客园"));
输出:博客园,,您好。很高兴认识你!