.NET编程笔记

1.类型.Parse()函数的参数只能是string类型的变量,Convert.To类型()参数只能是能相互兼容的类型变量,不一定是string变量。
 
2.CLR(公共语言运行时)、CTS(公共类型系统)、CLS(公共语言规范)、CIL(公共中间语言)。
 
3.一个程序集(例如mscorlib.dll)可以包含任意个命名空间,每个命名空间又可以包含多种类型。
 
4.类型包括:类、接口、结构、枚举、委托。
 
5.C#语言规范:项目名、命名空间、类文件名、类名、方法名、属性名首字母大写,变量名首字母小写,常量全部大写。
 
6.Main方法默认是私有的,返回0表示正常结束。
 
7.默认情况下,浮点数是double类型,要声明为float在后面加F或f,默认int,要设置为long,在后面加L或l。
 
8.结构和枚举是分配在栈上的值类型,string和object是引用类型,变量分配在托管堆上。
 
9.逐字字符串@"string"可以使得对一个字面量的转义字符的处理失效并输出字符串。
 
10.var关键字只能用于方法或属性范围内的本地变量,不能用于定义返回值、参数或自定义类型的字段数据。
 
11.尽量少用var关键字,只有在LINQ返回值时采用var,其他情况下尽量不用。
 
12.if语句中的判断条件只能是布尔表达式,不能是-1和0之类的。
 
13.switch语句除了数值数据之外,还可以计算字符串数据。
 
14.参数传入函数的默认行为是按值传递,out类型参数必须要赋值,且调用时要加out,params参数只能有一个,并且必须是最后一个参数。
 
15.可选参数必须放在方法签名的最后。
 
16.结构和枚举是派生自System.ValueType,而System.ValueType是派生自System.Object,它重写了System.Object的虚方法使其在栈而不是堆上实现。
 
17.值类型包含引用类型时,赋值时,非引用成员是深拷贝,引用成员默认是浅拷贝。
 
18.按值传递引用类型是复制了指向调用者对象的引用,按引用传递引用类型时参数就是调用者对象的别名。
 
19.如果按引用传递引用类型,被调用者可能改变对象的状态数据的值和所引用的对象;如果按值传递引用类型,被调用者可能改变对象的状态数据的值,但不能改变所引用的对象。
 
20.一旦定义了自定义构造函数,默认构造函数就会被自动从类中移出。
 
21.this关键字还可以代指重载的构造函数中的一个,只要参数匹配,this(arg1,arg2,..)调用构造函数,这样参数少的可以调用参数多的,节省代码量。
 
22.public static int fun(int arg1,int arg2);静态成员只能操作静态数据或调用类的静态方法。
 
23.静态构造函数用来初始化静态变量。
 
24.使类不能创建对象的3种方法:构造函数私有、定义成抽象类、定义成静态类。
 
25.public、internal:类型或者类型成员;public、private、protected、protected internal:类型成员或者嵌套类型,internal只能在当前程序集中访问。
 
26.默认情况下,类型成员是隐式私有的,类型是隐式内部的。
 
27.属性中的value是上下文关键字,属性可以有静态属性来操作静态数据,不允许构建只读或只写的自动属性。
 
28.必须使用构造函数重写分配给隐藏返回字段的默认值。
 
29.对象初始化语法只是使用默认构造函数创建类变量并设置各个属性状态数据的语法的简写形式。
 
30.常量const字段是隐式静态的,也是类级别的,定义常量时必须为常量指定初始值。public const int a = value。
 
31.构造函数是在运行时调用的,只读字段可以在运行时决定,只能在构造函数中赋值,其他地方不行。
 
32.C#结构(struct)总是隐式密封的,C#类使用sealed来防止发生继承,public sealed class CTest。
 
33.使用base关键字来调用基类构造函数。
 
34.一旦基类定义的方法为虚方法,则不管经过几次继承,即使派生类中没有显示加virtual,该方法仍然是虚方法,仍然可以被重写,如果从某一级继承开始不想被重写,则可以public override sealed void Fun,加上sealed来阻止后面重写该虚方法。
 
35.抽象类中可以有属性、字段、函数、虚方法、抽象方法(public abstract void Draw()),虚方法不是必须重写的,抽象方法是必须重写的。
 
36.使用new关键字来显式声明派生类型的实现故意设计为隐藏父类的版本(非virtual),例如:public new void Draw(); public new string PetName{set; get;}。
 
37.显式强制转换是在运行时而不是编译时进行运算,可以使用as关键字在运行时快速检测某个类型是否和另外一个兼容。ClassA a = b as ClassA; if (a == null) Console.WriteLine("not ClassA");
 
38.C#使用is来判断两个项是否兼容。
 
39.Object类的Equals函数,默认是比较的项指向内存中同一项才返回true,继承的类可以改写成只要被比较的对象有相同的内部状态值则返回true(这样更加符合常识)。如果没有重写Object的ToString函数,则默认返回对象的<namespace>.<type>字符串,一般要重写以符合用户所需要的输出形式。
 
40.一般如果一个类重写了Equals方法,也要重写GetHashCode方法,用可以唯一判断对象的string字段产生HashCode。
 
41.Object的静态方法Equals也是默认比较是否指向同一内存,ReferenceEquals也是比较是否指向同一内存,但是静态方法不能重写,所以一般是重写虚方法Equals,来实现比较字段值是否相等。
 
42.自定义异常应该派生自System.ApplicationException类型,所有自定义异常类都应该定义为公共类。
 
43.属性也可以重写。自定义异常类需要定义一个默认的构造函数,捕捉异常时,最前面的catch块捕捉最特定的异常,最后面的catch块捕捉最普通的异常。
 
44.只使用throw;会把原始异常抛出而不会创建新的异常对象抛出。
 
45.在处理一个异常时遇到另一个异常,最好的习惯是将这个新异常对象标识为与第一个异常类型相同的新对象中的“内部错误”。
 
46.finally块中的语句不管是否有异常发生都会执行。
 
47.可以重写类的Finalize方法,来为类型执行必要的清理逻辑,但该方法只能被垃圾回收器调用。
 
48.在结构上重写Finalize方法是不合法的,但可以实现IDisposable接口。
 
49.重写Finalize的唯一原因是,C#类通过PInvoke或复杂的COM互操作性任务使用了非托管资源。
 
50.重写Finalize方法只能通过终接器语法来重写,不能直接override Finalize方法。
 
51.结构和类类型都可以实现IDisposable接口,用来释放非托管资源,调用Dispose方法。
 
52.using语法,既可以指定命名空间,也可以保证using语句引用的实现了IDisposable接口的对象在退出using块后自动调用Dispose方法。
 
53.使用Lazy<>泛型可以延迟创建对象。
 
54.接口只能包含抽象成员,而抽象类可以包含非抽象成员,接口不指定基类,但可以指定基接口。接口成员不指定访问修饰符,默认是隐式公共的和抽象的。
 
55.接口不能有字段、构造函数,不能提供具体实现,接口还可以包含只读属性、事件以及索引器定义。
 
56.实现接口成员函数时把public加上去,不需要使用override,但重写基类函数时需要加override。
 
57.在运行时判断一个类型是否支持一个指定接口的一种方法是使用显式强制转换,如果不支持会收到一个无效转换异常。第二种方法是使用as关键字。第三种方法是使用is。
 
58.显式接口实现:returnType InterfaceName.MethodName(params),显式实现的方法默认私有,不能加访问修饰符,只能通过显式强制类型转换来使用。
 
59.IEnumearble接口内部有一个GetEnumerator方法,该方法返回IEnumerator对象,实现了GetEnumerator方法就可以使用foreach进行调用了。
 
60.使用yield return可以将返回的对象自动构造成IEnumerator对象来方便foreach调用。而且使用yield实现GetEnumerator方法时不需要继承自IEnumerable接口。
 
61.yield关键字可以构建命名迭代器,接收许多参数,返回IEnumerable接口对象,方法名可任意。
 
62.克隆过程:如果有一个仅包含值类型的类或结构,使用MemberwiseClone实现Clone方法。如果有一个保持其他引用类型的自定义类型,需要建立一个考虑了每个引用类型成员变量的新对象。
 
63.装箱的定义:显式地将值类型分配给System.Object变量的过程。当我们对一个值进行装箱操作时,CLR会在堆上分配新的对象,将值类型的值复制到那个实例上。因此,返回给我们的是新分配在堆上的对象的引用。
 
64.非泛型存在装箱拆箱的性能问题以及类型安全,泛型大幅减少了构建自定义集合类型的需要,而且不存在性能问题和安全问题,因此一般使用泛型集合。
 
65.IComparer接口实现后一般是辅助类作为参数传入比较函数或者构造函数。
 
66.使用default参数设置类型默认值,X = default(T);将X设置为类型T的默认值,数值的默认值是0,引用类型的默认值是null,一个结构的字段被设为0(值类型)或null(引用类型)。
 
67.实现接口定义的方法时不需要加override关键字,实现基类抽象方法或重写基类虚方法时需要override。
 
68.和传统的C++喊上指针不同,.NET委托是内置支持多路广播和异步方法调用的对象。.NET委托既可以指向静态方法,也可以指向实例方法。
 
69.可以直接使用方法名给委托赋值。协变允许我们构建一个委托,能指向返回类及相关继承体系的方法。而逆变是参数是存在传统继承关系的对象。
 
70.public delegate void MyGenericDelegate<T>(T arg);定义一个泛型委托。
 
71.公共的委托成员打破了封装,不仅会导致代码难以维护和调试,还会导致应用程序的安全风险。
 
72.匿名方法定义event += delegate(object o,eventargs e){...};匿名方法可以访问外部变量但不能访问定义方法中的ref和out参数,匿名方法中的本地变量不能与外部方法中的本地变量重名,但可以与外部类的成员变量同名,匿名方法可以访问外部类作用域中的实例变量(或静态变量)。
 
73.Lambda表达式只是用更简单的方法来写匿名方法。delegate(){}定义的是匿名方法,是方法而不是委托。
 
74.Lambda表达式可以理解为:ArgumentsToProcess => StatementsToProcessThem。
 
75.Lambda表达式实例:i => i%2 == 0;有大括号时执行语句才加分号,没有大括号时就不加。
 
76.操作符重载时,[]、()以及简写赋值操作符(如+=、-=等)都不可重载。
 
77.operator关键字只可以与静态方法联合使用。在C#中,如果一个类型重载了相关的二元操作符,这些简写赋值操作符会自动具有相应的新功能。
 
78.C#中重载++和--时,只需重载一种形式,而不需考虑前置后置问题,在调用时返回值会自动进行正确的处理。
 
79.C#重载==是必须同时重载!=,静态操作符重载函数调用时不需要加类名。
 
80.重载操作符通常仅在构建使用工具类型时才有用。如果一个重载操作符会使用户更难于理解该类型的功能,那就别用它。
 
81.public static explicit/implicit operator B(A a){ } 显式/隐式转换操作符方法定义。定义了隐式转换例程后,调用者使用显式强制类型转换语法是合法的。
 
82.使用拓展方法,可以为预编译的类型添加功能,同时这些方法将独立分开存放。
 
83.拓展方法只能定义在静态类中,且必须定义成静态的,第一个参数必须使用this进行修饰,大多数情况下,拓展方法的第一个参数表示被拓展的类型,每一个拓展方法只可以被内存中正确的实例调用,或者通过其所处的静态类被调用。
 
84.直接调用类的静态方法语法:classname.funname(params);但是通过实例调用拓展方法时不需要加类名,静态调用拓展方法也需要加类名。
 
85.拓展方法不能直接访问他们拓展的类型的成员,可以使用 (变量名.成员名) 来访问公共成员,就跟一般外部方法一样。
 
86.只要引用所指向的对象是派生类对象,则通过该引用所调用的方法用于是派生类重写过的方法,而与引用本身类型无关,因为这里看的是实际的对象。
 
 
87.拓展接口方法时需要提供具体实现。
 
88.分部方法只可以定义在分部类中,必须返回void,可以是静态或实例级别的,可以有参数(不能有out参数,其他都可以),总是隐式私有的。
 
89.分部方法使用partial关键字进行定义,编译器会根据方法体是已经实现的还是空的签名来决定方法是否应该放到程序集中。如果没有方法体的话,所以方法的使用痕迹(调用、元数据描述以及原型)都会在编译的时候去除。
 
90.匿名类型的名称完全由编译器决定。对于匿名对象,如果两个匿名类型有相同的属性并且被赋予了相同的值,就会产生相同的散列值,即GetHashCode()方法返回值相同。对于匿名对象,编译器重写了Equals方法,在判断对象相等时使用了基于值的语义(例如比较两个对象的每一个数据成员的值),而没有重载相等操作符(==和!=),因此使用相等操作符时,只要当两个引用指向同一内存对象才会返回true。
 
91.匿名类型的字段和属性总是只读的,匿名类型不支持事件、自定义方法、自定义操作符和自定义重写,匿名类型是隐式封闭(sealed)的,匿名类型的创建只使用默认构造函数。
 
92.任何时候在不安全代码上下文中与引用类型交互,都要固定该引用,使用fixed关键字保证引用类型不被垃圾回收器回收。
 
93.一般来说,在获取LINQ查询的结果集时,应该总是使用隐式类型。在绝大多数情况下,真正的返回值是实现了泛型IEnumerable<T>接口的类型。
 
94.LINQ是延迟执行的,就是说没调用一次结果集变量就执行一次查询,这样始终保持结果集是最新的。
 
95.LIQN返回查询结果时,要么使用IEnumerable<T>返回,要么调用ToArray()方法将结果变成数组返回。
 
96.LINQ的查询操作符是设计用于任何实现了IEnumerable<T>接口的类型的,无论是直接地还是通过拓展方法间接实现的。非泛型集合对象调用OfType<T>方法将非泛型转换为兼容IEnumerable<T>的类型从而可以使用LINQ查询。
 
97.数据、泛型集合、非泛型集合都可以使用LINQ查询。
 
98.可以使用完全限定名来解决命名冲突问题,namespace.classname,还可以使用using来对类名或命名空间取别名,using newName = namespacename/namespace.classname。
 
99.定义嵌套命名空间时一般使用namespace name1.name2{}来定义,而不是在name1命名空间下直接定义name2,一般使用"."来表示嵌套层次。
 
100.程序集名不同,即使命名空间和类名都相同,也认为是不同的类。
 
101.添加引用后,并不是立刻在debug文件夹下就将dll拷贝过来了,而是编译运行后才会把dll文件拷过来,而且项目中引用的命名空间是拷贝过来的dll里的,而不是原来位置的,这样方便项目部署。
 
102.AssemblyInfo.cs文件包含了大量描述程序集自身的特性。引用私有dll后,虽然vs会复制到exe目录下,但是原dll项目更新后,再编译exe项目使用dll时,vs会自动检查dll版本,始终确保最新的dll复制到exe目录下调用。
 
103.使用Assembly.Load()方法时,CLR将只探测客户端文件夹,因此必须把需要的dll拷贝到程序目录下。
 
104.通过动态加载程序集,使用晚期绑定得到类型,建立类型object对象,使用反射来调用object对象实际类型内部的方法。
 
105.[Serializable]是特性,一个特性只能被应用在紧接下来的对象。
 
106.特性是派生自System.Attribute的类,特性导致嵌入的元数据,直到被其他代理反射,特性才发挥使用。
 
107.处于安全性的原因,考虑吧所以的自定义特性都设计成密封类是一个好习惯。
 
108.自定义了特性之后,就要自定义如何反射特性。
 
109.在控制台输出时,可以使用"\t"来对结果格式进行规整化处理。
 
110.添加了[Synchronization]特性的类型将被加载到线程安全的上下文中(同步的上下文)。
 
111.dynamic关键字是一个特殊形式的System.Object,动态类型不是强类型的,动态数据不是静态类型。
 
112.dynamic关键字不能使用Lambda表达式和C#匿名方法,动态数据点无法理解拓展方法,动态变量不能用于LINQ to Object以及其他LINQ技术,无法进行编译时检查,不能触发智能感知等。
 
113.委托对异步方法调用的支持,允许用户自动地在次线程中调用某个方法,不需要手工创建或配置线程。
 
114.委托可以自动创建次线程,也可以使用Threading命名空间来手动创建。
 
115.使用Thread.Start方法创建的线程都自动成为前台线程。
 
116.要使得一个类的所有方法都是线程安全的,可以继承自ContextBoundObject类,并使用[Synchronization]特性。
 
117.当试图锁定的是一个实例级对象的私有方法时,使用方法本身所在对象的引用就可以了,即lock(this),如果需要锁定公共成员中的一段代码,比较安全的方式是声明私有的object成员来作为锁标识。
 
118.线程池中的线程总是后台线程,可以直接使用,不需要手工创建。
 
119.并行执行不代表异步执行,两者是不同的概念。
 
120.FileInfo对象的Open、Create、OpenRead、OpenWrite返回FileStream对象,而OpenText返回StreamReader对象,CreateText、AppendText返回StreamWriter对象。
 
121.File的静态方法实现FileInfo实例对象方法的功能。
 
122.FileStream可以读取文件,但是只能以字节数组方式读取。StreamReader和StreamWriter可以直接以字符串对文件进行读取,StringReader和StringWriter可以直接以字符串形式对内存或字符数据流写入或读取信息。
 
123.[Serializable]特性是不能被继承的,只要是对象图中的所有对象必须标上[Serializable]特性。
 
124.使用XmlSerializer序列化对象时,只能序列化公共的(包括类型、字段、方法等),而其他两种公共私有都可以。
 
125.XmlSerializer需要一个默认的构造函数。
 
126.定义自定义构造函数后,手动添加一个默认构造函数是良好的编程习惯。
 
127.序列化对象集时使用集合类型List<T>就行了。
 
128.DataReader要保持连接,不缓存结果集,并且只能执行Select语句,不能修改数据库。
 
129.实现接口抽象成员不等于给抽象成员赋值,而是实现具体方法以及将抽象属性用具体字段来实现,赋值时实例层次的,而实现接口抽象成员是类层次的。
 
130.函数、属性、类名、项目名、命名空间名以大写字母开头,字段、变量、函数参数已小写字母开头,常量全大写。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

.NET编程笔记,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。