CodeGym /课程 /C# SELF /构造函数和对象初始化

构造函数和对象初始化

C# SELF
第 16 级, 课程 3
可用

1. 简单构造函数

构造函数 —— 这是类里的一个特殊方法,在你创建对象时会自动调用。它用来初始化(配置)对象:设置初始值、做些检查,甚至你想写个冷笑话在里面也行,说不定能让你心情好点。

构造函数让你能直接把对象创建成某种状态,而不用手动一个个字段和属性去赋值。这很方便也更安全,因为你一开始就把所有重要参数都写清楚了——不会忘了啥关键东西。

没有构造函数的话,代码会很啰嗦,还容易出错:

Person p = new Person();
p.Name = "Julia";
p.Age = 25; // 如果忘了写年龄会咋样?

有了构造函数:


Person p = new Person("Julia", 25); // 一步到位,对象直接能用了!

构造函数语法

构造函数就是一个特殊的“方法”,它的名字和类名完全一样,而且没有返回值(连void都没有)。下面是默认构造函数的样子:


public class Person
{
    // 默认构造函数(无参数)
    public Person()
    {
        // 这里可以写初始化代码
    }
}
默认构造函数

默认构造函数就像个隐形“小助手”,它不接收任何参数,只是把你类里的所有字段和属性都初始化成默认值:

  • 数值类型(int、double、float等)默认是0。
  • 布尔类型(bool)默认是false。
  • 引用类型(string、其他类)默认是null(就是“啥都没有”,没有对象的引用)。
  • DateTime默认是01.01.0001 00:00:00。

怎么调用构造函数?

其实你写new操作符创建对象时,就是在调用构造函数!

Person p = new Person();

如果你啥构造函数都没写,C#编译器会帮你自动生成一个默认构造函数(无参数)。但只要你自己写了一个构造函数,默认的那个就没了,如果还想要,得自己手动加回来。

例子

来给我们的应用加个构造函数。下面是学生类的简单版本:


public class Student
{
    public string Name;
    public int Age;

    // 带两个参数的构造函数(名字和年龄)
    public Student(string name, int age)
    {
        Name = name; // 给字段赋值
        Age = age;
    }
}

现在可以这样创建学生对象:

Student s = new Student("Joe", 21);
Console.WriteLine($"{s.Name}: {s.Age} 岁"); // Joe: 21 岁
  • 我们声明了和类一样可见性的构造函数(public)。
  • 构造函数里用传进来的参数给字段赋值。
  • 这样能防止忘记赋值:编译器会强制你创建对象时写上名字和年龄。

2. 构造函数参数

在C#里你可以声明多个构造函数,参数列表不一样。这叫构造函数重载(方法重载以后还会讲)。

比如,加一个无参数的构造函数:

public class Student
{
    public string Name;
    public int Age;

    // 默认构造函数
    public Student()
    {
        Name = "无名氏";
        Age = 0;
    }

    // 带参数的构造函数
    public Student(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

现在两种写法都可以:


Student s1 = new Student();          // 名字: 无名氏, 年龄: 0
Student s2 = new Student("Helga", 22); // 名字: Helga, 年龄: 22

用构造函数做校验

构造函数是个很好的地方用来检查传进来的数据靠不靠谱。比如,学生年龄不能是负数!


public Student(string name, int age)
{
    if (age < 0)
        throw new ArgumentException("年龄不能是负数!");
    Name = name;
    Age = age;
}

现在如果有人想创建Student("Malysh", -2),程序会直接抛异常(ArgumentException)。这种写法很常见,用来保证数据“铁打的靠谱”。

3. 复杂对象的初始化

实际开发里,一个对象经常不只是基本类型,还会包含别的对象:

public class Group
{
    public string GroupName;
    public Student[] Students;

    public Group(string groupName, Student[] students)
    {
        GroupName = groupName;
        Students = students;
    }
}

现在可以很方便地创建一个带学生数组的组:

var students = new Student[]
{
    new Student("Joe", 20),
    new Student("Maria", 19)
};
Group g = new Group("组-101", students);

字段默认值初始化

有时候你想给某些字段设个默认值,如果构造函数参数没传的话。比如,e-mail不是必填项:

public Student(string name, int age)
{
    Name = name;
    Age = age;
    Email = "unknown@noemail.com"; // 默认值
}

4. 用Object Initializer初始化

构造函数还能和另一种很方便的写法配合用——对象初始化器。你可以先调用构造函数,然后用花括号写上新对象的属性值:


public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }

    // 构造函数还是推荐写
    public Student(string name, int age)
    {
        Name = name;
        Age = age;
        Email = "";
    }
}

Student s = new Student("Anton", 18) { Email = "anton@domain.com" }; // 构造函数+属性

这种写法和构造函数配合特别好用,尤其是有些参数有默认值或者创建时还不确定。

5. 常见错误和注意点

用构造函数时,新手经常会踩几个坑。咱们来举例说说:

错误1:名字写错
有时候参数名和字段名只差大小写,很容易搞混。


public Student(string Name, int Age) // 首字母大写!
{
    Name = Name; // 哎呀!两个Name都指参数,字段没赋值。
}

正确写法: 用this指向对象的字段:

public Student(string name, int age)
{
    this.Name = name;
    this.Age = age;
}

或者直接用不同的名字(比如nameParam、ageParam),不过用this.是好习惯,尤其是大项目里。

错误2:没有默认构造函数

如果你写了至少一个构造函数,然后又想无参数创建对象——编译器会报错:

public class Student
{
    public Student(string name) { /*...*/ }
}

// 某处代码
Student s = new Student(); // 错误!没有无参数构造函数。

解决方法: 显式加一个无参数构造函数:

public Student() { /*...*/ }

错误3:死循环——构造函数自己调用自己


public Student()
{
    // 错误!自己调用自己——死循环。
    new Student();
}
2
任务
C# SELF, 第 16 级, 课程 3
已锁定
带参数的构造函数
带参数的构造函数
2
任务
C# SELF, 第 16 级, 课程 3
已锁定
初始化包含数组的复杂对象
初始化包含数组的复杂对象
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION