上周虽然没上课,课上的内容是部分同学展示大作业成果,但是对于我来说,看了一些同学辛勤劳动的成果,听了他们对C#学习的一些感悟,我受益匪浅。
在这里我想谈谈我的收获。老师给的模板是todolist,但是绝不局限于todolist,很多同学都做的是备忘录,但是各有千秋,有的加入了优先级功能,即可以在备忘录中按照重要程度分类,这样可以筛选出重要的信息,将一些不重要的内容先隐藏什么的。还有一些同学做的是游戏,我感觉难度是相当大的。比如有的同学用到了游戏引擎,借助于其处理一些复杂的细节。于是我了解了一些C#中游戏引擎的开发问题,发现Unity3d在游戏开发中占据了很重要的地位,于是对这进行了一番了解。以下是我的一番见解。
一、委托
如果你熟悉C语言,并且向其他人描述委托,你一定会立刻想到“函数指针”。实际上,委托在某种程度上提供了间接的方法,即,不需要直接指定一个行为,而是将这个行为用某种方式“包含”在一个对象中。这个对象可以像其他任何对象那样使用。在该对象中,可以执行封装的行为。可以选择将委托类型看做只定义了一个方法的接口,将委托的实例看做实现了那个接口的一个对象。因此,委托必须满足4个条件:
- 声明委托类型;
- 必须有一个方法包含了要执行的代码;
- 必须创建一个委托实例;
- 必须调用委托实例。
二、值类型和引用类型
我这里就不具体说这两种类型,只说下这两个类型的差异:
- 对于值类型的表达式,它的值就是表达式的值,而对于引用类型的表达式,它的值是一个引用,而不是该引用所指代的对象。在存储方面,值类型变量总是存储在栈中,引用类型实例总是存储在堆中;
- 值类型不可以派生出其他类型。对于引用类型来说,每个对象的开头都包含一个数据块,它标识了对象的实际类型。并且永远都不能改变对象的类型—执行简单的强制类型转换时,运行时会获取一个引用,检查它引用的对象是不是目标类型的一个有效的对象。若果有效,就返回原始引用;否则抛出异常。引用本身并不知道对象的类型,所以同一个引用“值”可用于不同类型的多个变量。
知道了这两个差异后,就可以很好的理解装箱和拆箱了。如果我们不想用值类型的值,就是想用一个引用。C#提供了一个名为装箱的机制,它允许根据值类型来创建一个对象,然后使用对这个新对象的一个引用。
例如:
Int i= 5; Object o = i; Int j = (int) o; |
这里有两个变量:i是值类型的变量,o是引用类型的变量。这里发生的事情就是装箱:运行时将在堆上创建一个包含值(5)的对象(它是一个普通对象)。o的值是对该新对象的一个引用。该对象的值是原始值的一个副本,改变i的值不会改变箱内的值。
第三行执行相反的操作—拆箱。必须告诉编译器将object拆箱成什么类型。如果使用错误的类型,就会抛出一个InvalidCastException异常。同样,拆箱也会复制箱内的值,在赋值之后,j和该对象之间不再有任何关系。