Archive for the Category »笔记 «

1、  C#里面的继承有两种:实现继承和接口继承。前者表示一个类型派生于一个基类型,拥有该基类型的所有成员字段和函数;后者表示一个类型只继承了函数的签名,没有继承任何的实现代码。
2、  C#不像C++支持多重继承,但是可以派生于另一个类和任意多个接口
3、  结构总是派生于System.ValueType,它们还可以派生于任意多个接口;类总是派生于用户选择的另一个类,它们还可以派生于任意多个接口。
4、  C#中虚拟函数的声明方式为:
access-identifier virtual return-type function-name()
成员字体和静态函数都不能声明为virtual
在基类中重载虚函数用关键字override
access-identifier override return-type function-name()
5、  C#中用关键字new隐藏基类中的同名但是非虚函数
access-identifier new return-type function-name()
6、  在C++中抽象类不能实例化,而抽象函数没有执行代码。C#中对抽象的定义是相同的,用法则是要加上关键字abstract。抽象的也是虚拟的,但是不需要加上virtual,并且如果加上的话将会是一个语法错误。
access-identifier abstract class-name/function-name
7、  C#中引入了一个C++中没有的概念:密封
什么是密封呢?对于类来说,这表示不能继承该类;对于方法来说,这表示不能重写该方法。
access-identifier sealed class-name/function-nam
8、  下面是C#中修饰符的具体意义:
修饰符
应用于
说明
public
所有的类型或成员
任何代码均可以访问该成员
protected
类型和内嵌类型(即在一个类中定义的类)的所有成员
只有派生的类型能访问该成员
internal
类型和内嵌类型的所有成员
只能在包含它的程序集中访问该成员
private
所有的类型或成员
只能在它所属的类型中访问该成员
protected internal
类型和内嵌类型的所有成员
能在包含它的程序集派生类型中访问该成员
 
 
 
new
函数成员
成员用相同的签名隐藏继承的成员
static
所有的成员
成员不在类的具体实例中执行
virtual
仅函数成员
成员可以由派生类重写
abstract
类和函数成员
抽象成员定义了成员的签名,但没有提供实现代码
override
仅函数成员
成员重写了继承的虚拟或抽象成员
sealed
成员重写了继承的虚拟成员,但继承该类的任何类都不能重写该成员。必须与override一起使用
extern
仅静态[DllImport]方法
成员在外部用另一种语言实现
9、  声明接口在语法上与声明抽象类完全相同
access-identifier interface name
但不允许提供接口中任何成员的执行方式。一般情况下,接口中只能包含方法、属性、索引器和事件的声明。不能实例化接口,在接口定义中还不允许声明成员上的修饰符。
Category: 笔记  Leave a Comment
前两天为了做一个项目,很努力的把Beginning C# Objects看完了,对C#的大概语法也有一点点的了解,so,最近开始看传说中很有名的Professional C# 2005(和Primer差不多大的砖头…看上去好像还要厚一些…),刚刚看完第三章—对象和类型,其实C#和C++还是有一定的类似的,所以看起来不痛苦,但是还是有一些不同的地方和新的特性。
1、 传递参数的方式:值传递,ref传递与out传递
值传递:当在参数前面没有任何修饰符的时候所有的参数都是通过值传递来进行的,这个和C++是类似的。
Ref传递:当要改变实参的值时,C++是采用指针的方式,而C#是用ref [type] para这样的形式,需要注意的是在调用函数的时候也要加上ref args
Out传递C#中如果没有对传递给方法的参数进行初始化,那么是不允许在函数体里改变其值的,然后如果仅仅是想用函数输出多个值,而又不愿意初始化,那么可以采用out传递,具体的与ref相同。
2、  方法的重载
重载方法是一个很好的技术,重载时只能由参数数量,类型不同来区别,这点C#和C++是一样的,然后C#多了两个关键字ref和out,是不是可以用这个来区分两个重载函数呢?答案是否定
3、  Property
个人很欣赏这个特性,这样就不用特意写一对Set和Get函数来保证对类的数据成员的合法访问了,而且代码看上去更加intuitive。
4、  构造函数
构造函数方面,C#有一个很有意思的特例:如果提供了带参数的构造函数,编译器就不会自动提供默认的构造函数,只有在没有定义任何形式的构造函数时,编译器才会自动提供。这与C++不同,C++是只要程序员没有提供默认构造函数,那么编译就会为你提供。
提供用private/protected定义的构造函数有两个目的:a)类仅用作某些静态成员或属性的容器,因此永远不会实例化。b)希望类仅通过调用某个静态成员函数来实例化(这就是所谓对象实例化的类代理)
C#还提供一种比较新颖的构造函数类型:静态构造函数。这种构造函数只执行一次。定义方式:static ClassName(){// initialization code}。注意,无参数的实例构造函数可以在类中与静态构造函数安全共存,并不会因为他们的方法签名相同而出现编译错误。但是,.NET运行库并没有确保静态构造函数什么时候执行,所以不要把代码放在某个特定的时刻(例如,加载程序集时)执行。也不能预计不同类的静态构造函数按照什么执行,但是,可以确保静态构造函数至多运行一次,即在代码引用类之前执行。
最后,是类似C++的构造函数初始化符,即constructor() : 中的这个冒号。除了语法类似之外,C#初始化符所包含的代码遵循完全不同的规则。可以使用C++初始化列表指定成员变量的寝值,或调用基类构造函数,而C#初始化符中的代码只能调用另一个构造函数,这就要求C#类在构造时遵循严格的顺序。
5、  只读字段
C#提供一个readonly关键字,它比const灵活得多。const指定的变量的初始值必须是编译时能够确定的,然而readonly则没有这个要求。但是其规则是只能在构造函数中给只读字段赋值。如果没有赋值,那么它的值就是数据类型的默认值。这适用于静态与实例只读字段。
6、  C#中的结构和C++的结构完全不是一个概念,在C++中,struct和class是一个概念,只是关键字不同,而为了让C程序员能够适应而遗留下来的,然后C#中,结构是值类型,在栈上分配,而类是引用类型,在堆上分配。结构的生存期的限制与简单的数据类型类似,不支持继承,编译器总是为结构提供一个无参数的默认构造函数,不允许替换,可以指定字段如何在内存中布局。
结构可以用new来新生成一个对象,也可以像普通值变量那样赋值。
 
Category: 笔记  6 Comments

前两天看的内容先不做了,有复习的时候看到有价值的再放上来,今天看到一个有意思的,先弄上来省得以后翻书忘了~~我想读书笔记的作用就在于此吧,把自己认为有用的记录下来,以后就不用常翻书了,翻一本书是一本实在痛苦的事情……

[quote]
si.cbSize = sizeof( SCROLLINFO );
si.cbMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = NUMLINES – 1;
si.nPage = cyClient / cyChar;

SetScrollInfo( hwnd, SB_VERT, &si, TURE );
[/quote]

这样做以后Windows会把最大的滚动条位置设置为si.nMax – si.nPage + 1,而不是nMax,这就和直接用SetScrollRange不同了,用这个函数的最基本用法就是:

[quote]
SetScrollRange( hwnd, SB_VERT, 0, NUMLINES – 1, FALSE );
SetScrollPos( hwnd, SB_VERT, iVScrollPos, TRUE );
[/quote]

这样做会引起一个问题,就是当滚动条的位置是0的时候,第一行信息显示在客户区的顶部(这当然是没问题的,也符合我们平时的使用),可是如果当滚动条的位置是NUMLINES – 1时,最后一行显示在客户区的顶部,并且看不见其他行,这就和平时我们用的有点区别的了,我们平时使用时是最后一行显示在最后一行,并且此时滚动条已经到底了,而如果要用SDK实现这个功能就要改一下

[quote]
iVScrollMax = max( 0, NUMLINES – cyClinet / cyChar );
SetScrollRange( hwnd, SB_VERT, 0, iVScrollMax, TRUE );
[/quote]

这实在是有一点麻烦,但是SetScrollRange用MSDN里面的话是provides a backward compability,所以两种方法还是要掌握的,当然在XP下SetScrollInfo优先~~[lol]

Category: 笔记  3 Comments