### 一句话概括
*object
类型(也叫 System.Object
)是C#中所有类型的“老祖宗”,它是整个类型体系的终极基类。**
这意味着你在C#里用的每一个变量,无论是数字、字符串、你自己定义的类,甚至是数1
,它们最终都继承自 object
。
---
### 一个生动的比喻
想象一个**家族树**:
* object
就像是这个家族最古老的共同祖先。
* 他的孩子有 值类型
家族(比如 int
, double
, struct
)和 引用类型
家族(比如 string
, 各种 class
)。
* 你再自定义一个 Person
类,那它就是 引用类型
家族的孩子,也就是 object
的曾孙。
所以,**万物皆对象** 这句话在C#里是非常贴切的。正因为所有东西都是 object
的孩子,所以它们都能做 object
会做的事情。
---
### object
类型提供了哪些“通用技能”?
由于它是所有类型的基类,它定义了几个所有类型都具备的基本方法:
1. *ToString()
方法:转换成字符串**
* 作用:获取一个对象的字符串表示形式。
* 默认行为:默认返回对象**类型的完整名称**(例如 "System.Int32"
)。但很多常用类型(如 int
, string
)已经重写了这个方法,使其返回更有意义的值(比如数字 5
会返回字符串 "5"
)。
* 何时使用:在需要将对象输出显示给用户时非常有用,比如 Console.WriteLine(任何对象);
内部其实就是调用了它的 ToString()
。
2. *Equals()
方法:判断是否相等**
* 作用:判断当前对象与另一个对象是否“相等”。
* 默认行为:对于**引用类型**(如 class
),默认比较的是两个**引用是否指向同一个内存地址**(是不是同一个对象),而不是比较对象的内容。对于**值类型**(如 struct
),默认会比较所有字段的值。
* 何时使用:当你需要判断两个对象是否相等时。通常对于自定义的类,我们会重写这个方法来实现比较对象**内容**是否相同。
3. *GetHashCode()
方法:获取哈希码**
* 作用:返回一个代表该对象的int数值(哈希码)。如果两个对象相等(根据 Equals
方法),那么它们的哈希码**必须**相同。
* 何时使用:主要用于基于哈希的集合类,如 Dictionary<T>
(字典)和 HashSet<T>
(哈希集),这些集合用它来快速定位和比较对象。
4. *GetType()
方法:获取类型信息**
* 作用:返回一个 Type
对象,其中包含了关于当前对象类型的所有信息(比如它叫什么名字、有什么方法、有什么属性等)。这是一个非常强大的反射(Reflection)功能的基础。
* 何时使用:当你在运行时需要知道一个变量到底是什么具体类型时。
---
### 两个重要的概念:装箱和拆箱
这是使用 object
时必须了解的概念。
* 装箱 (Boxing):将一个**值类型**(如 int
)的值包裹起来,转换成 object
引用类型的过程。
```csharp
int number = 42; // 值类型,在栈上
object obj = number; // 装箱!将number的值“装箱”到一个放在堆上的object中,obj指向这个盒子。
```
* 拆箱 (Unboxing):从 object
中提取出原始**值类型**的过程。
```csharp
object obj = 42;
int number = (int)obj; // 拆箱!必须用强制转换告诉编译器盒子里装的是什么类型。
```
注意:装箱和拆箱有性能开销,因为它涉及内存的分配和拷贝,应避免在大量循环中进行。
---
### 代码示例
```csharp
using System;
class Program
{
static void Main()
{
// 1. 万物皆object
object obj1 = 10; // 装箱一个int
object obj2 = "Hello"; // 存放一个string引用
object obj3 = new Person { Name = "Alice" }; // 存放一个自定义类的引用
// 2. 使用通用方法
int num = 42;
Console.WriteLine(num.ToString()); // 输出: "42"
Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };
// 默认比较引用(地址),因为是两个不同的对象
Console.WriteLine(person1.Equals(person2)); // 输出: False
// 3. 获取类型
Type type = obj1.GetType();
Console.WriteLine(type.Name); // 输出: Int32
}
}
class Person
{
public string Name { get; set; }
// 在实际开发中,我们通常会重写Equals和GetHashCode方法来比较Name属性
}
```
### 总结
| 特点 | 解释 |
| :----------- | :----------------------------------------------------------- |
| 终极基类 | 所有类型都直接或间接继承自 object
。 |
| 通用方法 | 提供 ToString()
, Equals()
, GetHashCode()
, GetType()
等所有类型都具备的方法。 |
| 万能容器 | object
类型的变量可以存储任何类型的值(但值类型会发生**装箱**)。 |
| 性能注意 | 与值类型互操作时要注意**装箱和拆箱**的开销。 |
对于初学者,最重要的是理解 “万物皆对象” 这个概念object
就像是一个通用接口或通用盒子,让你可以用一种统一的方式去处理各种不同类型的数据,这是C#类型系统强大和灵活的基础。