在 C# 中,object 和 var 的区别可以用一句话概括:object 是一个具体的类型,而 var 是一个语法糖,用来让编译器自动推断类型。
下面从几个关键维度拆解它们的区别:
object:是所有类型的基类。当你声明一个变量为 object,你就是在明确告诉编译器:这个变量可以指向任何类型的对象(值类型会被装箱)。
var:不是类型,只是一个关键字,让编译器根据右边的赋值表达式推断出具体的类型。推断出的类型可以是 int、string、自定义类、甚至 object 本身。
示例:
csharpobject a = "hello"; // a 的类型就是 object
var b = "hello"; // b 的类型被推断为 string
object:使用 object 时,编译器只知道它是 object,访问其成员时只能使用 object 类定义的方法(如 ToString()、Equals())。如果需要调用实际类型的特定方法,必须进行强制类型转换。
var:编译器在编译时就会推断出具体类型,之后所有代码都按这个具体类型来检查。可以直接访问该类型的任何成员,无需转换。
示例:
csharpobject obj = "text";
var str = "text";
// obj.Length; // 编译错误:object 没有 Length 属性
int len1 = ((string)obj).Length; // 需要强制转换
// str.Length; // 正确:str 是 string 类型,可以直接访问 Length
int len2 = str.Length;
object:如果用于值类型(如 int、bool),会发生装箱操作,把值类型数据从栈上封装到堆上的 object 对象中,有性能开销。
var:由于推断出的是具体值类型,不会发生装箱,直接使用栈上的值。
示例:
csharpobject o = 42; // 装箱:int 被包装成 object
var v = 42; // v 的类型是 int,没有装箱
| 场景 | 推荐 | 原因 |
|---|---|---|
| 需要存储多种不同类型的对象(如异构集合) | object | 因为 object 可以持有任何类型。 |
| 使用匿名类型 | var (必须) | 匿名类型没有名字,只能用 var 声明。 |
| 代码可读性与明确意图 | 看情况 | var 可以减少重复代码(如 Dictionary<string, List<int>>),但也可能让类型不直观;object 明确表示“这里不在意具体类型”。 |
| 性能敏感的值类型操作 | var (或具体类型) | 避免 object 导致的装箱开销。 |
反射、类型判断、GetType() 等操作 | object | 你需要一个基类引用来调用 GetType() 或者进行类型判断。 |
| 特性 | object | var |
|---|---|---|
| 本质 | 类型 (System.Object) | 关键字 (语法糖) |
| 确定时机 | 声明时确定 | 编译时根据赋值推断 |
| 类型安全 | 需要强制转换才能访问具体成员 | 完全类型安全,编译时检查 |
| 值类型开销 | 会装箱 | 无装箱 |
| 能否为 null | 能 (引用类型) | 取决于推断出的类型 (值类型不能) |
| 匿名类型 | 不能直接声明 | 必须使用 |
| 方法参数 | 可以作为参数类型 | 不能用于参数 (必须明确类型) |
| 类成员 | 可以作为字段类型 | 不能用于字段 |
误解:var 像 object 一样是弱类型或动态类型。
事实:var 是强类型的,只是让编译器替你写类型名而已。下面的两行代码完全等价:
csharpvar i = 10; // 编译器推断为 int
int i = 10; // 显式声明 int
object。var。object,用 var 或显式类型。var,必须明确类型 (C# 不支持 var 成员)。本文作者:ZeroEngineer
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!