Menu
CoddyTech

用于封装的属性

本课属于 Coddy C# 学习旅程的“面向对象编程”单元。第 32 课,共 70 课。

属性是在 C# 中实现封装的主要工具。你可以用属性包装字段,而不是直接公开字段,从而控制数据的访问和修改方式。

这种模式将私有字段与公共属性结合起来,并在访问器中加入验证或逻辑:

public class Temperature
{
    private double celsius;
    
    public double Celsius
    {
        get { return celsius; }
        set
        {
            if (value < -273.15)
                celsius = -273.15;  // 最低为绝对零度
            else
                celsius = value;
        }
    }
}

现在,外部代码无法设置无效的温度。这个属性就像把关者,确保你的对象始终处于有效状态。这就是封装的实际应用:内部数据受到保护,同时仍可通过受控接口访问。

你还可以使用属性来计算值或触发副作用:

public double Fahrenheit
{
    get { return celsius * 9 / 5 + 32; }
    set { celsius = (value - 32) * 5 / 9; }
}

外部世界能看到两个属性,但内部实际上只有一个字段。属性可以让你在不破坏使用你的类的代码的前提下更改实现细节,这是良好封装的一大优势。

challenge icon

挑战

简单

让我们构建一个使用属性来保护数据完整性的产品库存系统。你将创建一个类,确保价格不会变成负数,数量始终处于有效范围内,展示属性如何充当数据的守门员。

你需要将代码分成两个文件:

  • Product.cs:在 Inventory 命名空间中创建一个 Product 类,通过属性管理产品信息并进行验证。你的产品需要包含:
    • 一个私有字段 price(decimal),以及一个公共属性 Price,确保价格不会低于 0。如果有人尝试设置负价格,则应将其存储为 0
    • 一个私有字段 quantity(int),以及一个公共属性 Quantity,确保值介于 0 和 1000 之间。低于 0 的值变为 0,高于 1000 的值变为 1000
    • 一个公共自动实现属性 Name(string)
    • 一个只读计算属性 TotalValue,返回 Price * Quantity
    添加一个构造函数,按名称、价格和数量的顺序接收这些参数,并通过属性设置所有值,以便应用验证。
  • Program.cs:在主文件中,使用输入值创建一个 Product。然后尝试使用额外的输入值修改价格和数量,这些值可能无效。分别在创建后和每次修改后打印产品状态,看看属性如何保护数据。

你将收到 5 个输入:

  • 产品名称
  • 初始价格(decimal)
  • 初始数量(整数)
  • 要设置的新价格(decimal,可能为负数)
  • 要设置的新数量(整数,可能超出范围)

按以下格式打印输出:

After creation:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
After modifications:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}

例如,如果输入是 Laptop、999.99、50、-100 和 1500,输出应为:

After creation:
Laptop: Price=999.99, Qty=50, Total=49999.50
After modifications:
Laptop: Price=0, Qty=1000, Total=0

注意,负价格变成了 0,数量 1500 被限制为 1000。你的属性正在保护对象,使其不会处于无效状态,这就是封装的作用!

亲手试试

using System;
using Inventory;

class Program
{
    public static void Main(string[] args)
    {
        // 读取输入
        string name = Console.ReadLine();
        decimal initialPrice = Convert.ToDecimal(Console.ReadLine());
        int initialQuantity = Convert.ToInt32(Console.ReadLine());
        decimal newPrice = Convert.ToDecimal(Console.ReadLine());
        int newQuantity = Convert.ToInt32(Console.ReadLine());

        // TODO: 使用初始值创建一个 Product 对象
        
        // TODO: 输出创建后的产品状态
        Console.WriteLine("After creation:");
        // 输出格式:{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
        
        // TODO: 用新值修改价格和数量
        
        // TODO: 输出修改后的产品状态
        Console.WriteLine("After modifications:");
        // 输出格式:{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C# 在线编译器