现在的位置: 首页 > 综合 > 正文

类型和成员基础

2012年12月03日 ⁄ 综合 ⁄ 共 2597字 ⁄ 字号 评论关闭

本文PDF下载

类型基础

所有类型都从Syetem.Object派生

运行时要求每个类型最终都从System.Object类型派生。换言之,以下两个类型的定义是完全一致的:

隐式派生自Object

    public class Employee

    {

        public string Name { get; set; }

    }

显式派生自Object

    public class Employee : Object

    {

        public string Name { get; set; }

    }

由于所有类型最终都从System.Object派生,所以可以保证每个类型的每个对象都有一组最基本的方法。具体来说,System.Object类提供了如下的公共实例方法:

公共方法名称

说明

Equals

确定两个 Object 实例是否相等。

GetHashCode

用作特定类型的哈希函数。

ToString

返回表示当前 Object String

GetType

获取当前实例的 Type

此外,从System.Object派生的类型可以访问如下所示的受保护方法:

受保护方法名称

说明

MemberwiseClone

创建当前 Object 的浅表副本。

Finalize

允许 Object 在“垃圾回收”回收 Object 之前尝试释放资源并执行其他清理操作。

CLR要求所有的对象都用new关键字进行创建:

Employee employee = new Employee();

以下过程是new操作符所作的事:

1.         计算类型及其所有基类型中定义的所有实例字段所需要的字节数。

2.         从托管堆中分配指定类型所需的字节数,从而分配内存空间。

3.         初始化对象的“类型对象指针”(type object pointer)与“同步块索引成员”(sync block index)。

4.         调用实例的构造器,向其传入在对new的调用中指定的任何实参。

new执行了这些操作之后,会返回指向新建对象的一个引用。在前面的示例中,这个引用会保存到变量employee中,后者具有Employee类型。

因为Employee类型从Syetem.Object派生,所以Employee类型实例就具有了Syetem.Object定义的可访问的实例方法。以ToString()方法为例,它在默认情况下输入完整类型名称:

代码:

            Employee employee = new Employee();

            employee.Name = "Sunny D.D";

            Console.WriteLine(employee.ToString());

输出:

clip_image002

当然我们也可以重写ToString()方法,以获得想要的结果:

    public class Employee : Object

    {

        public string Name { get; set; }

        public override string ToString()

        {

            return Name;

        }

    }

clip_image004

 

类型转换

CLR最重要的特性之一就是类型安全性。在运行时,CLR总是可以调用GetType()方法得到一个对象的确切类型是什么。由于GetType()是非虚方法,所以一个类型不可能伪装成另一个类型。例如,Employee类型不能重写GetType()方法,从而返回一个String类型。即便你可以使用new关键字覆盖此方法,但CLR是在基类型Object上调用此方法的,所以仍然可以得到当前对象的确切类型:

    public class Employee : Object

    {

        public string Name { get; set; }

        public override string ToString()

        {

            return Name;

        }

        public new Type GetType()

        {

            return typeof(String);

        }

    }

调用:

            Employee employee = new Employee();

            Console.WriteLine(employee.GetType());

            object objEmployee = employee;

            Console.WriteLine(objEmployee.GetType());

结果:

clip_image006

在实际开发过程中,我们常需要将对象从一种类型转换为其他类型。CLR允许将一个对象转换为它的实际类型,或者它的任何基类型。

C#中,不需要任何特殊语法即可将一个对象转换为它的任何基类型,因为向基类型的转换被认为是一种安全的转换。然而,将对象转换为它的某个派生类型时,C#要求必须进行显式转换,因为这可能在运行时失败。以下代码演示了基类型与派生类之间的相互转换:

            object o = new Employee();

            Employee e = (Employee)o;

这个例子展示了你需要做什么,才能让编译器顺利的编译代码。接着,我将演示一个虽然可以通过编译,但会在运行时抛出一个InvalidCastException(因无效类型转换或显式转换引发的异常):

    public class Manager : Employee

    {

    }

调用:

            Employee e = null;

            object m = new Manager();

            e = (Employee)m;

            object d = new DateTime(1984, 10, 17);

            e = (Employee)d;

结果:

clip_image008

可以看到,在上述代码实际执行过程中,发生的第一次转换e = (Employee)m;成功了,这是由于m的类型Manager是从Employee派生的,所以CLR成功执行类型转换,继续往下进行。而在第二次转换e = (Employee)d;时,CLR抛出了一个异常,这是因为d的类型DateTime既不是一个Employee

抱歉!评论已关闭.