字段是直接在类或结构中声明的任何类型的变量。 字段是其包含类型的成员。
类或结构可能具有实例字段、静态字段或两者。 实例字段是特定于某个类型实例的。 如果有一个类 T
(具有实例字段 F
)可以创建两个类型 T
对象,并修改每个对象中的值 F
,而不会影响其他对象中的值。 相比之下,静态字段属于类型本身,并在该类型的所有实例之间共享。 只能使用类型名称访问静态字段。 如果通过实例名称访问静态字段,则会出现 CS0176 编译时错误。
通常,应为字段声明 private
或 protected
访问权限。 应通过 方法、 属性和 索引器提供类型向客户端代码公开的数据。 通过使用这些构造来间接访问内部字段,您可以防范无效的输入值。 存储公共属性公开的数据的专用字段称为 后盾存储 或 后盾字段。 可以声明 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
、、private
、protected
internal
、或protected internal
private protected
。 这些访问修饰符定义类型用户如何访问字段。 有关详细信息,请参阅访问修饰符。
可以选择声明 static
字段。 静态字段随时可供调用方使用,即使不存在该类型的实例也是如此。 有关详细信息,请参阅 静态类和静态类成员。
可以声明 readonly
字段。 只读字段只能在初始化期间或在构造函数中分配值。
static readonly
字段类似于常量,只是 C# 编译器在编译时无权访问静态只读字段的值(仅在运行时)。 有关详细信息,请参阅 常量。
可以声明 required
字段。 必填字段必须在对象创建时由构造函数或对象初始值进行初始化。 将属性 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute 添加到初始化所有必需成员的任何构造函数声明。
不能在同一字段上同时使用required
修饰符和readonly
修饰符。 但是,属性只能是required
和init
。
从 C# 12 开始, 主构造函数 参数是声明字段的替代方法。 当类型具有必须在初始化时提供的依赖项时,可以创建提供这些依赖项的主构造函数。 可以捕获这些参数并将其用于代替类型中声明的字段。 对于 record
类型,主要构造函数参数显示为公共属性。
C# 语言规范
有关详细信息,请参阅 C# 语言规范。 语言规范是 C# 语法和用法的明确来源。