C#14、new关键字的作用是什么?
·
在 C# 中,new 关键字有 三种主要用途,作为初级工程师,你需要掌握它们各自的场景和区别:
✅ 1. 创建对象实例(最常用)
这是 new 最常见的用法:在堆上分配内存并调用构造函数,创建类或结构体的实例。
示例:
// 创建类的实例(引用类型)
Person person = new Person("Alice", 25);
// 创建结构体的实例(值类型)
Point p = new Point(10, 20);
// C# 9+ 支持目标类型推断(更简洁)
Person person2 = new("Bob", 30); // 编译器知道要创建 Person
💡 底层发生了什么?
- 为对象分配内存(类在堆上,struct 在栈或内联)
- 调用对应的构造函数初始化字段
- 返回对该对象的引用(或值副本)
✅ 2. 隐藏基类成员(成员隐藏 / Shadowing)
在派生类中,用 new 修饰符可以隐藏(不是重写)基类中同名的成员。
示例:
class Base
{
public void Say() => Console.WriteLine("Base");
}
class Derived : Base
{
public new void Say() => Console.WriteLine("Derived"); // 隐藏基类方法
}
调用效果:
Derived d = new Derived();
d.Say(); // 输出 "Derived"
Base b = d; // 向上转型
b.Say(); // 输出 "Base"!因为是隐藏,不是多态重写
⚠️ 注意:
- 这不是多态!它只是“名字覆盖”,运行时根据变量类型决定调用哪个方法。
- 如果不用
new,编译器会警告:“隐藏继承成员,请使用 new 显式隐藏”。- 和
override完全不同:override是真正的重写,支持多态。
✅ 3. 泛型约束(where T : new())
在泛型中,new() 约束表示:类型参数 T 必须有一个公共的无参构造函数。
示例:
public static T CreateInstance<T>() where T : new()
{
return new T(); // 可以安全调用 new T()
}
// 使用
var list = CreateInstance<List<int>>(); // ✅ List<int> 有无参构造
var person = CreateInstance<Person>(); // ✅ 前提是 Person 有 public 无参构造
❌ 如果
T没有无参构造函数(比如只有带参构造),编译会报错。
📌 三种用法对比表
| 用法 | 场景 | 示例 |
|---|---|---|
| 创建实例 | 实例化类或结构 | new MyClass() |
| 隐藏成员 | 派生类中隐藏基类同名成员 | public new void Method() |
| 泛型约束 | 要求泛型类型有无参构造 | where T : new() |
⚠️ 常见误区
❌ 误区1:new 总是分配在堆上
✅ 正解:
new Class()→ 堆new Struct()→ 栈(或内联),但语法上仍用new
❌ 误区2:new 隐藏 = override 重写
✅ 正解:
new是编译时绑定(看变量类型)override是运行时多态(看实际对象类型)
❌ 误区3:所有类型都能 new()
✅ 正解:接口、抽象类不能直接 new(除非有具体实现)。
💡 初学者建议
- 日常最常用的是第 1 种:创建对象。
- 第 2 种(隐藏)尽量少用,容易造成混淆,优先考虑
virtual + override实现多态。 - 第 3 种在写通用工具方法(如工厂、序列化)时很有用。
问题
在泛型类中如何创建类型T的新对象?
必须为类型T添加new约束,然后使用此类型的构造函数。
有多少种用法?
new运算符,修饰符,约束
更多推荐
所有评论(0)