checked关键字
用来检查赋值是否数据溢出,或者在VS中配置,项目-属性-生成-高级,检查上溢下溢。
1 | checked //unchecked 不检查 |
委托
2种写法:
1 | Calcul cal=new Calcul(Add); |
情况2自动初始化一个委托。
二维数组
1 | int[,] ints = new int[10,4]; |
ref out关键字
ref out 等也可以改变函数的签名(命名+参数),从而实现重载
断点
可以设置中断条件和击中次数。如,a>=100,次数=100。
析构函数
1 | class MyClass{ |
~ 析构函数,垃圾回收器回收时自动调用,还将隐式调用基类的析构函数。
隐藏基类方法,在子类中定义时加
1 | new public void Do(){ |
类型比较
1 | myObj.GetType()==typeof(MyObjClass) |
对象类型的比较:
myObj is objBase
,myObj是objBase的子类,实现类,同类都为true。
重载运算符,例如:+
需要在进行+运算的类内部定义。
- 不能重载+=,-=。但如果重载它们对应的简单运算符,如+,则+=仍能像预期那样执行
- 不能重载=,因为它有基本用途
- 不能重载&&和||,但同1理,重载&和|就够了
- <和>,<=和>=必须成对重载
1 | class Person |
IComparable接口
定义在要比较的对象的类中实现,类要实现IComparable接口。
1 | public int CompareTo(object obj) |
重写隐式(implicit),显式(explicit)转换
1 | class Person1 |
同样可作用于泛型集合。
父子类相互转换
1会报错,2不会报错。不能把父类实例转换成子类实例,只能把父类变量类型转换成子类变量类型。
1 | //1 |
如果强转换成as 则都不会报错,1为null,2不为null。
??运算符
1 | int? val1 = null; |
??等式的结果可以是int或int?,等式会自动进行转换。
default关键字
如果T是引用类型,则输出null。
如果T是值类型,则输出默认值。e.g.int -> 0。
1 | class MyClass<T>{ |
约束类型
1 | class MyClass<T1, T2> : MyClassBase |
- 约束类型:struct值类型,class引用类型,base-class任意基类,interface接口,new()有一个公共无参构造函数
- 多个约束之间用,分隔
- new()作约束必须是指定的最后一个
- 约束必须出现在继承说明符的后面
协变和抗变
应用于泛型接口和委托,继承关系默认支持协变。
协变
1 | List<string> liststr = new List<string>(); |
定义:
1 | public class List<T> : IEnumerable<T>... |
- 使用关键字out,则类型参数T只能作为方法的返回值
- 泛型类型参数可以从一个派生类隐式转化为基类,让一个带有协变参数的泛型接口(或委托)可以接收类型更加精细化,具体化的泛型接口(或委托)作为参数,可以看成OO中多态的一个延伸
抗变(逆变)
1 | class MyComparer : IComparer<object> |
定义:
1 | public interface IComparer<in T> |
- 使用关键字in,则类型参数T只能作为方法的参数
- 泛型类型参数可以从一个基类隐式转化为派生类,让一个带有协变参数的泛型接口(或委托)可以接收粒度更粗的泛型接口或委托作为参数,这个过程实际上是参数类型更加精细化的过程
总结:
协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值);逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确。
引发事件时,会依次调用程序列表中每个处理程序,只要它们满足指定的条件即可
委托的应用
1 | delegate int OperationDelegate(int left,int right); |
- 用方法创建委托:
void Function(new OperationDelegate(OperationEx));
- 直接传递方法(默认创建委托):
void Function(OperationEx);
- 匿名方法:
void Function(delegate(int left,int right){ return left+right; });
- Lambda表达式:
1 | void Function((left,right) => left+right); |
Lambda表达式的解释
可以用两种方式解释Lambda表达式。
第一,Lambda表达式是一个委托,可以把它表示为如下泛型类型:
Action - lambda表达式不带参,返回void;
Action<> - lambda表达式最多8个参数,返回void;
Func<> - lambda表达式最多8个参数,返回不是void;
e.g.Func
第二,可以把Lambda表达式解释为表达式树:
并不能直接执行。LINQ架构的泛型类 Expression<>,可用于封装Lambda表达式,把它转换为相应的SQL脚本,以便在数据库中直接执行。
工作目录
1 | //设置当前工作目录,并不是转移文件! |
FileStream
1 | FileInfo file = new FileInfo("test.txt"); |
FileStream读取数据
1 | //读取本身cs文件 |
FileStream写入
1 | byte[] byData; |
StreamReader/Writer的权限
StreamReader/Writer 总是拥有对文件的读写权限,为了使用高级参数如,FileMode,FileAccess,可以在FileStream构造函数指定这些参数,然后通过FileStream创建StreamReader/Writer。
读取数据的选择
1,小文件,StreamReader.ReadToEnd();
2,大型文件,StreamReader.ReadLine();
循环判断是否为空或者
1 | foreach (var item in File.ReadLines("test.txt",Encoding.Default)) |
压缩和解压缩类 输入读取类
System.IO.Compression
1 | static void SaveCompressedFile(string fileName, string data) |
C#6.0 新特性
- 字符串插值(String Interpolation)
之前:
1 | var Name = "Jack"; |
Now:
1 | var results = $"Hello {Name}"; |
之前:
1 | Person p = new Person {FirstName = "Jack", LastName = "Wang", Age = 100}; |
Now:
1 | var results = $"First Name:{p.FirstName} LastName:{p.LastName} Age:{p.Age}"; |
还可以插入代码 - 相当于小脚本或Razor 的@{ },不过只能作用于string。
1 | Console.WriteLine($"Jack is saying { new Tools().SayHello() }"); |
- 空操作符 ( ?. )
之前:
1 | if (user != null && user.Project != null && user.Project.Tasks != null && user.Project.Tasks.Count > 0) |
Now:
1 | Console.WriteLine(user?.Project?.Tasks?.First()?.Name); |
还可用于数组索引器:
1 | User[] users = null; |
以下代码并不会报错,也不会有输出。减少了空异常,但是我们却需要小心使用,因为有的时候我们确实是需要抛出空异常。那么使用这个特性反而隐藏了Bug。
1 | User user = null; |
C#6.0 新特性 2
- NameOf
1 | Console.WriteLine(nameof(User.Name)); // output: Name |
NameOf只会返回Member的字符串,如果前面有对象或者命名空间,NameOf只会返回 . 的最后一部分, 另外NameOf有很多情况是不支持的,比如方法,关键字,对象的实例以及字符串和表达式。
- 表达式方法体
一句话的方法体可以直接写成箭头函数,而不再需要大括号。
1 | private static string SayHello() => "Hello World"; |
序列化对象
1 | using System.IO; |
监控文件
1 | private FileSystemWatcher watcher; |
XPath查询xml语言
1 | XmlDocument xml = new XmlDocument(); |
LINQ查询大数集合
1 | private static int[] GetNumbers(int count) |
LINQ 2
单值查询:.Distinct()(只选取没有重复的元素)
任意符合:.Any()(任意元素符合条件返回true)
全部符合:.All()(全部元素符合条件返回true)
.First()和.FirstOrDefault()区别:
.First()当条件不满足时,抛出异常;
.FirstOrDefault()当条件不满足时,返回一个null;
LINQ 3
集运算符:
.Intersect():使用默认的相等比较器得出两个序列的交集
.Except():同上,得出差集
.Union():同上,得出并集
Join查询:
1 | var orderIds = from n in list select n; |
LINQ TO XML
1 | //从字符串转换 |