《CLR via C#》读书笔记 之 基元类型、引用类型和值类型 明

第五章 基元类型、引用类型和值类型

2013-02-27

5.3 值类型的装箱和拆箱
    5.3.2 对象的相等性和同一性
参考

ToDo: 什么时候使用值类型,什么时候使用引用类型 

5.3 值类型的装箱和拆箱


返回

 1 struct Point
 2 {
 3     public Int32 x, y;
 4 }
 5 public static class Program
 6 {
 7    public static void Main()
 8    {
 9        System.Collections.ArrayList a = new System.Collections.ArrayList();
10        Point p;
11        p.x = p.y = 1;
12        a.Add(p);      //对值类型进行装箱,因为Add方法原型:public virtual int Add(object value)
13        p = (Point)a[0]; //对已装箱的Point对象进行拆箱
14    }
15 }

装箱过程:

(1)       在托管堆分配好内存。

(2)       把值类型的字段复制到新分配的堆内存

(3)       返回对象的地址。

拆箱过程:

(1)       获取已装箱的值对象的各个字段地址

(2)       把字段的值复制到基于栈的值类型字段中

值类型调用方法注意:

(1)       若值类型重写基类的虚方法,可以非虚的调用,因为值类型是隐式密封的,没有类从它们派生。

(2)       若要调用非虚的、继承的方法,那么在调用时,值类型实例会装箱,以便通过this【1指针将对一个对象的引用传给基方法。

(3)       若将值类型的一个未装箱实例转型为类型的某个接口时,要求对实例进行装箱,因为接口变量必须包含对堆上对象的引用

5.3.2 对象的相等性和同一性

返回

System.Object类型提供了一个名为Equals的虚方法,基本实现如下

1 public class Object
2 {
3     public virtual Boolean Equals(Object obj)
4     {
5         //若指向同一对象,返回true
6         if (this == obj) return true;
7         return false;
8     }
9 }

以上代码实现的是同一性,而非相等性。而且以上实现也不合理,下面展示如何在内部正确实现一个Equals方法:

(1)       若Obj实参为null,就返回false,因为在调用非静态的Equals方法时,this所标识对象不可能为null。

(2)       若this和obj实参引用的是同一对象,返回true

(3)       若this和obj实参引用类型不同,返回false

(4)       若类型定义的每个实例字段,任何一个不相等,返回false

(5)       调用基类型的Equals方法,一般比较它定义的任何字段。

由于System.Object的虚方法Equals可以重写,所以不能调用它来测试同一性,因此,Object提供了一个静态方法ReferenceEquals,原型如下:

1 public class Object
2 {
3     public static bool ReferenceEquals(object objA, object objB)
4     {
5         return (objA == objB);
6     }
7 }

若想检查同一性,务必使用ReferenceEquals,而不是==操作符(除非先把两个操作数都转型为Object),因为==也可以被重载。

System.ValueType(所有子类型基类)重写了Object.Equals方法,并进行了正确的实现来执行相等性测试,实现如下:

(1)       若obj实参为null,返回false

(2)       若this和obj实参引用不同类型对象,返回false

(3)       对每个实例字段进行比较,任何一个字段不等,返回false

(4)       返回true,ValueType的Equals方法不调用Object的Equals方法。

参考

返回

【1】C# this关键字详解 http://developer.51cto.com/art/200909/148868.htm

原文地址:https://www.cnblogs.com/Ming8006/p/2934739.html