星期四 十一月 26, 2009 20:18
csharp对象和类的学习笔记
如左图所示(点击查看大图),首先这一章需要理清的一对关系是,结构和类。这里尤其需要说明的是:
- 虽然结构本身不支持继承,但隐藏在他背后的还是有一条鲜为人知的继承链:Struct继承于System.ValueType,而System.ValueType继承与System.Object。除此“一脉相传”之外,你不允许给他指定任何基类,也不允许从任何结构继承点什么。在我看来,这样的框架设计也正好符合了“万事万物皆对象”的原则。
- 结构的默认构造函数会将其申明的字段初始化为标准的默认值,直接对字段进行赋值初始化会遭到编译器的拒绝。但,重载构造函数可以绕过这个限制。(c# professional 2008 P155 Constructors for Structs在这一点上貌似提的有些问题)
在我早先的知识结构中,编程这块主要是C和Java。所以对于下面提到的一些问题会有点陌生:
函数成员->方法->传递参数->out关键字。与之相对的有一个ref关键字。ref挺好理解的,就是按引用传递,貌似c中的按地址传递参数。c#中,无论是值传递,还是引用类型传递,都需要先进行初始化。但真正在编程的过程中,初始化的数据往往是不重要的,甚至有的时候函数就没用过那些被初始化的数据,自然的不论是客户还是programer都希望看到的是计算后的那些amazing的,有意义的符号。out关键字,使得程序员能够摆脱这一初始化的僵局,当在方法参数中申明一个out变量时,编译器自动对其进行初始化,该变量通过引用传送。另外,在函数体内,如果未对out参数分配一个值的话,那编译器是不会通过验证的。当然,在调用该方法时,也需要继续指明out关键字。
函数成员->方法->方法重载(帅哥说咱这个阶段暂时只用记住2点:)
- 两个方法不能仅仅只在返回类型上有区别。
- 两个方法不能仅仅只在参数申明为out还是ref来区别。
函数成员->构造函数
有一个默默奉献的默认构造函数,不论你是否重构构造函数,还是压根没有动手描述它,它总是会隐式的自动调用,并为我们将字段初始化为标准的默认值,其功能也仅限于此。不过,下述情况是个意外。
把构造函数private化(也就是传说中的对象实例化的类代理),直接实例化是不可能实现的,因为在外部,new是没有办法使用的。一般来说,这样做是为了:
- 作为储存静态成员或属性的容器。
- 仅通过调用某个静态函数成员来实例化(可以保证在程序中只有一个该类的实例,需加锁)demo如下,注意观看getAtestClassInstance方法。
class Program
{
static void Main(string[] args)
{
testClass t = testClass.getAtestClassInstance(100);
Console.WriteLine(t.b);
Console.WriteLine(t.c);
}
class testClass
{
private static int a;
public int b;
public int c;
private static testClass t;
private static object locker = new object();
private testClass(int a)
{
testClass.a = a;
c = a;
}
public static testClass getAtestClassInstance(int a)
{
if (t == null)
{
lock(locker)
{
t = new testClass(a);
}
}
return t;
}
}
}
静态构造函数,又是第一次遇到。我想事到如今,或许我们可以总结为:only one吗?请用static。如上述的getAtestClassInstance方法,保证只有一个实例运行。静态构造函数一般有这样几点值得注意和总结:
- 静态构造函数保证至多运行1次,在代码引用类之前,demo如下。
- 静态构造函数没有访问修饰符,没有其他的c#代码访问它,永远只有.net自己调用。
- 静态构造函数不能带参数,一个类只能有一个静态构造函数。
- 无参的实例构造函数与静态构造函数安全共存,因为二者的运行时间不同。
class Program
{
static void Main(string[] args)
{
Console.WriteLine(testClass.a);
new testClass();
Console.WriteLine(testClass.a);
}
class testClass
{
public static int a;
public int b;
static testClass()
{
System.Random r = new Random();
a=r.Next(10);
}
}
}
只读字段的使用规则是,只能在声明时,或构造函数中进行初始化。
扩展方法是一个静态方法,没有放在类的源代码中。虽然是静态方法,但必须使用实例来调用。如果原类中包含与扩展方法同名的方法,则扩展方法无效。
- Category: csharp-note
- (1) Comment

cSharp继承的学习笔记-PartOne | 邵明博的个人博客
十一月 28th, 2009 at 12:35 上午
[...] 最近这两天的效率实在是低。昨天是相当于一整天只更新了一篇关于《对象和类》的日志,而今天只看了继承这一章的1/6 的内容。持续的低迷,精神状态是一方面的原因——午睡的时间给耽误了,加上早先的几天的熬夜,显得这几天看书效率低了好几个档次。另外,今天下午还是铁着心,跑出去买了一个PNY 的浪漫紫罗双子盘+一个昂达的方块糖P3 ,很心疼的说。提起U盘,那真是一头包的,月头才买不久的Sandisk 就神不知鬼不觉的不见了;提起这次买的P3,让我想起04 年那会,昂达刚出第一款vx505 时,我就买了。 Tags: csharp, 学习笔记, 继承, 隐藏函数 [...]