0Pricing
C# Academy · 课时

仅限 init 的 setter

创建只能在初始化时设置的属性。

仅限 init 的 setter 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。

仅在初始化时设置

init 访问器允许属性在对象构造期间(包括使用对象初始化器时)进行设置,但之后会变为只读。其形式为 { get; init; }。

using System;

class Point {
    public int X { get; init; }
    public int Y { get; init; }
}

var p = new Point { X = 3, Y = 4 };
Console.WriteLine(p.X + "," + p.Y); // 3,4

仅在初始化时设置

对象构造完成后,为 init 属性赋值会产生编译错误,从而保证构造完成后的不可变性。

using System;

class Config {
    public string Name { get; init; }
}

var c = new Config { Name = "prod" };
// c.Name = "dev"; // compile error
Console.WriteLine(c.Name); // prod

对象初始化器仍然可用

与只读属性相比,init 的主要优势在于它支持对象初始化器语法,因此您不必为每个属性都编写一个构造函数。

using System;

class Settings {
    public bool DarkMode { get; init; }
    public int FontSize { get; init; }
}

var s = new Settings { DarkMode = true, FontSize = 14 };
Console.WriteLine(s.DarkMode + " " + s.FontSize); // True 14

与构造函数结合

您可以在构造函数中设置 init 属性,同时允许对象初始化器覆盖这些值。

using System;

class User {
    public string Role { get; init; } = "guest";
    public User() { }
}

var u = new User { Role = "admin" };
Console.WriteLine(u.Role); // admin

默认值

init 属性可以有默认初始化器,除非在构造期间被覆盖,否则将使用这些默认值。

using System;

class Options {
    public int Retries { get; init; } = 3;
}

Console.WriteLine(new Options().Retries);            // 3
Console.WriteLine(new Options { Retries = 5 }.Retries); // 5

初始化与设置

set 访问器允许随时修改值,而 init 只允许在构造阶段赋值。对于创建后不可变的数据,请选择 init。

using System;

class Mutable { public int V { get; set; } }
class Frozen  { public int V { get; init; } }

var m = new Mutable { V = 1 };
m.V = 2; // allowed
Console.WriteLine(m.V); // 2

带验证的初始化

您可以使用支持字段实现显式的 init 体,以验证所赋的值。

using System;

class Percentage {
    private int _value;
    public int Value {
        get => _value;
        init => _value = (value < 0 || value > 100)
            ? throw new ArgumentOutOfRangeException()
            : value;
    }
}

Console.WriteLine(new Percentage { Value = 80 }.Value); // 80

记录类型中的初始化

位置记录类型的属性默认仅能通过 init 设置,这正是记录类型既不可变又支持 with 复制的原因。

using System;

record Account(string Id, decimal Balance);

var a = new Account("A1", 100m);
Console.WriteLine(a.Balance); // 100

嵌套对象初始化器

init 支持嵌套对象初始化器,因此您可以通过一个表达式构建复杂的不可变对象图。

using System;

class Address { public string City { get; init; } }
class Person { public string Name { get; init; } public Address Home { get; init; } }

var p = new Person { Name = "Lin", Home = new Address { City = "Oslo" } };
Console.WriteLine(p.Name + " / " + p.Home.City); // Lin / Oslo

初始化与继承

派生类可以通过对象初始化器设置基类的 init 属性,因为构造阶段涵盖整个对象。

using System;

class Base { public int Id { get; init; } }
class Item : Base { public string Name { get; init; } }

var i = new Item { Id = 1, Name = "Pen" };
Console.WriteLine(i.Id + " " + i.Name); // 1 Pen

综合运用

完全使用 init 属性和对象初始化器构建的不可变数据传输对象。

using System;

class OrderDto {
    public int Id { get; init; }
    public string Customer { get; init; }
    public decimal Amount { get; init; }
}

var o = new OrderDto { Id = 7, Customer = "Ada", Amount = 49.9m };
Console.WriteLine(o.Id + " " + o.Customer + " " + o.Amount); // 7 Ada 49.9

快速检查

请检验您对仅初始化设置器的理解。

回顾

您已经了解了仅初始化设置器。

  • { get; init; } 只允许在构造期间赋值。
  • 对象初始化器可以与 init 属性结合使用。
  • 您可以通过显式的 init 体添加验证。
  • 记录类型的位置属性默认使用 init。

常见问题解答

「仅限 init 的 setter」课时是免费的吗?

是的 — 「仅限 init 的 setter」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。

「仅限 init 的 setter」这节课中我会学到什么?

创建只能在初始化时设置的属性。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C# Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「仅限 init 的 setter」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C# Academy 课中编写并运行代码吗?

能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 仅限 init 的 setter
  2. required 修饰符
  3. 不可变对象模式
  4. 记录类型中的 with 表达式
← 返回 C# Academy