1. 正确创建对象的方法
C#里的new操作符就像一颗魔法按钮,把一个“蓝图”(我们的类)变成一个真正能用的实例(对象)。简单说:类定义了对象能干嘛和它有啥属性,而new就是在内存里造出这个对象。
没有new,我们的类就像没有建成的图纸:你可以欣赏、讨论,但没法跳上去玩,也没法把茶洒在alcantara沙发上。
如果类是披萨的食谱,那new就是厨师,按这个食谱做出真正的美味披萨。对象就是成果:盒子里的披萨,可以直接吃掉。
语法
来看看怎么用这个万能的new。假如我们有个Contact类,基本语法如下:
Contact cont = new Contact();
- Contact在左边——这是我们要创建的变量类型。
- cont——变量名(起个有意义的名字,省得以后debug头疼)。
- new Contact()——调用new操作符,创建一个Contact类型的对象。
内存里的样子
当这段代码执行时,操作系统会为新对象分配一块内存,然后返回一个引用(地址),这个对象就“住”在那。这个引用保存在cont变量里。
示意图
+------------------+ +--------------------+
| 变量 cont | ---------> | Contact对象 |
+------------------+ +--------------------+
|
| (包含名字、电话、email等...)
|
地址
2. 创建联系人对象
在前面的例子里我们设计了这样一个类:
public class Contact
{
public string Name;
public string Phone;
public string Email;
}
现在来创建一个新的Contact对象:
Contact friend = new Contact();
friend.Name = "伊万 伊万诺夫";
friend.Phone = "+1-999-123-45-67";
friend.Email = "ivan@example.com";
Console.WriteLine($"名字: {friend.Name}, 电话: {friend.Phone}, Email: {friend.Email}");
这里发生了什么:
- 用new Contact()创建对象。
- 给它的字段赋值。
- 把数据打印出来。
例子2:
再来玩玩多个联系人——再创建一个对象:
Contact boss = new Contact();
boss.Name = "阿纳斯塔西娅 谢尔盖耶夫娜";
boss.Phone = "+1-888-765-43-21";
boss.Email = "nastya@company.com";
Console.WriteLine($"老板: {boss.Name}, 电话: {boss.Phone}");
是不是很像给每个熟人填表?对象就是这样工作的:每个实例都有自己独立的值,互不干扰!
3. 使用对象数组
如果我们要存不止一个、两个,而是比如说十个联系人,最合理的就是用数组:
Contact[] contacts = new Contact[3]; // 3个对象的数组
contacts[0] = new Contact();
contacts[0].Name = "丹尼斯";
contacts[0].Phone = "+7-911-111-22-33";
contacts[1] = new Contact();
contacts[1].Name = "玛丽亚";
contacts[1].Phone = "+7-915-123-45-67";
contacts[2] = new Contact();
contacts[2].Name = "彼得";
contacts[2].Phone = "+7-921-543-21-00";
// 打印所有联系人
for (int i = 0; i < contacts.Length; i++)
{
Console.WriteLine($"联系人 {i+1}: {contacts[i].Name}, {contacts[i].Phone}");
}
注意:我们要对数组里的每个元素都用new!创建数组本身不会创建对象,只是准备好放引用的位置。
4. new操作符和默认值
有时候会有人问——如果我只声明一个Contact类型的变量,但没用new给它赋对象,会发生什么?
Contact someContact;
someContact.Name = "错误"; // 编译错误!
如果你写成这样:
Contact someContact = null;
那你要是访问someContact.Name,程序就会“崩掉”,报出著名的异常:
System.NullReferenceException: 对象引用未设置为对象的实例。
为了避免这种情况,使用前一定要用new初始化对象。
5. 调用构造函数
当你写new Contact()时,其实会调用一个特殊方法——构造函数。目前我们的类没有显式构造函数,所以会用默认的构造函数,创建对象并把所有字段设为默认值(引用类型是null,数字是0)。
下一节你会学到怎么写自己的构造函数——比如直接传名字和电话。现在我们只有无参数构造函数。
现实生活的例子
用new操作符搞对象,是每个C#程序员的日常。想象一下你:
- 在网站上创建用户——代码里就有了一个新的User对象。
- 在网店下单——就有了新的Order。
- 录入一本书的数据——新Book对象。
任何现代C#程序里你都会看到成千上万行new操作符。
创建对象前的内存
Contact firstContact; // 变量,但啥都没指向
+--------------------------+
| firstContact |----> null (啥都没有!)
+--------------------------+
创建对象之后
Contact firstContact = new Contact();
+--------------------------+ +----------------------+
| firstContact |---------------->| Contact对象 |
+--------------------------+ +----------------------+
6. 实用例子
假如我们想让用户通过键盘输入来创建新联系人:
Console.WriteLine("请输入名字:");
string name = Console.ReadLine();
Console.WriteLine("请输入电话:");
string phone = Console.ReadLine();
Contact newContact = new Contact();
newContact.Name = name;
newContact.Phone = phone;
Console.WriteLine($"已保存联系人: {newContact.Name}, {newContact.Phone}");
现在每次用户输入都会在内存里创建一个独一无二的对象,可以存、改、打印——想怎么玩都行!
7. 常见错误和有趣的坑
错误1:忘了在用对象前调用new。
如果只声明变量没初始化,你要么编译报错,要么运行时遇到NullReferenceException。经典坑:声明了对象——如果真要用,立刻用new创建!
错误2:创建了对象数组,但没创建对象本身。
很多人会踩这个坑:你创建了Contact[]数组,但里面其实全是null。一旦访问contacts[0].Name就崩。必须先给每个元素单独初始化:contacts[i] = new Contact();。
错误3:把方法和属性搞混了。
新手有时会把方法当字段用:写student.GetName而不是student.GetName()。如果不马上用结果可能没事——但编译器会报错,如果你把“方法”放到需要值的地方。记住:方法要用圆括号调用,就算没参数也要写括号。
GO TO FULL VERSION