字段 (C# 编程指南)

字段是直接在结构中声明的任何类型的变量。 字段是其包含类型的成员

类或结构可能具有实例字段、静态字段或两者。 实例字段是特定于某个类型实例的。 如果有一个类 T(具有实例字段 F)可以创建两个类型 T对象,并修改每个对象中的值 F ,而不会影响其他对象中的值。 相比之下,静态字段属于类型本身,并在该类型的所有实例之间共享。 只能使用类型名称访问静态字段。 如果通过实例名称访问静态字段,则会出现 CS0176 编译时错误。

通常,应为字段声明 privateprotected 访问权限。 应通过 方法属性索引器提供类型向客户端代码公开的数据。 通过使用这些构造来间接访问内部字段,您可以防范无效的输入值。 存储公共属性公开的数据的专用字段称为 后盾存储后盾字段。 可以声明 public 字段,但不能阻止使用类型的代码将该字段设置为无效值,或者更改对象的数据。

字段通常存储必须可供多个类型方法访问的数据,并且必须存储的时间超过任何单个方法的生存期。 例如,表示日历日期的类型可能有三个整数字段:一个用于月份,一个用于日期,一个用于年份。 不在单个方法范围内使用的变量应声明为方法主体本身中的 局部变量

字段是在类或结构体块中通过指定访问级别、类型和字段名称来声明的。 例如:

public class CalendarEntry
{

    // private field (Located near wrapping "Date" property).
    private DateTime _date;

    // Public property exposes _date field safely.
    public DateTime Date
    {
        get
        {
            return _date;
        }
        set
        {
            // Set some reasonable boundaries for likely birth dates.
            if (value.Year > 1900 && value.Year <= DateTime.Today.Year)
            {
                _date = value;
            }
            else
            {
                throw new ArgumentOutOfRangeException("Date");
            }
        }
    }

    // public field (Generally not recommended).
    public string? Day;

    // Public method also exposes _date field safely.
    // Example call: birthday.SetDate("1975, 6, 30");
    public void SetDate(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        // Set some reasonable boundaries for likely birth dates.
        if (dt.Year > 1900 && dt.Year <= DateTime.Today.Year)
        {
            _date = dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }

    public TimeSpan GetTimeSpan(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        if (dt.Ticks < _date.Ticks)
        {
            return _date - dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }
}

若要访问实例中的字段,请在实例名称后面添加句点,后跟该字段的名称,如中所示 instancename._fieldName。 例如:

CalendarEntry birthday = new CalendarEntry();
birthday.Day = "Saturday";

在声明字段时,可以使用赋值运算符为字段提供初始值。 例如,若要自动将 Day 字段分配给 "Monday",可按以下示例声明 Day

public class CalendarDateWithInitialization
{
    public string Day = "Monday";
    //...
}

在调用对象实例的构造函数之前立即初始化字段。 如果构造函数分配字段的值,则会覆盖字段声明期间给出的任何值。 有关详细信息,请参阅 使用构造函数

注释

字段初始化表达式不能引用其他实例字段。

字段可以标记为public、、privateprotectedinternal、或protected internalprivate protected。 这些访问修饰符定义类型用户如何访问字段。 有关详细信息,请参阅访问修饰符

可以选择声明 static字段。 静态字段随时可供调用方使用,即使不存在该类型的实例也是如此。 有关详细信息,请参阅 静态类和静态类成员

可以声明 readonly字段。 只读字段只能在初始化期间或在构造函数中分配值。 static readonly字段类似于常量,只是 C# 编译器在编译时无权访问静态只读字段的值(仅在运行时)。 有关详细信息,请参阅 常量

可以声明 required字段。 必填字段必须在对象创建时由构造函数或对象初始值进行初始化。 将属性 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute 添加到初始化所有必需成员的任何构造函数声明。

不能在同一字段上同时使用required修饰符和readonly修饰符。 但是,属性只能是requiredinit

从 C# 12 开始, 主构造函数 参数是声明字段的替代方法。 当类型具有必须在初始化时提供的依赖项时,可以创建提供这些依赖项的主构造函数。 可以捕获这些参数并将其用于代替类型中声明的字段。 对于 record 类型,主要构造函数参数显示为公共属性。

C# 语言规范

有关详细信息,请参阅 C# 语言规范。 语言规范是 C# 语法和用法的明确来源。

另请参阅