文章目录
7.6.1 字段概念及用途
在C#中,字段(Field)是类或结构体中用于存储信息的成员。字段可以是任何数据类型,包括值类型(如 int
、double
、bool
等)、引用类型(如类、接口、委托)或者更复杂的数据结构(如数组、集合)。
字段的概念:
字段是类或结构体中声明的变量,用于存储数据。字段可以是公共的(public)、受保护的(protected)、私有的(private)或内部的(internal),以控制对字段的访问权限。
字段的用途:
-
数据存储:字段用于在对象中存储数据。
-
状态表示:字段可以表示对象的状态。例如,一个
Car
类可能有color
和speed
字段来表示汽车的颜色和速度。 -
常量定义:字段可以用作常量,即字段值在初始化后不可改变。
-
计算属性的后备存储:字段可以作为属性的后备存储,用于在属性的
get
和set
访问器中存储和检索数据。
字段的类型:
-
值类型字段:如
int
、float
、double
、bool
、char
、struct
。 -
引用类型字段:如
string
、class
。 -
静态字段:静态字段属于类,而不是类的实例。
-
常量字段:用
const
关键字声明,值不可改变。
示例代码:
public class Person
{
public string Name; // 公共字段
private int age; // 私有字段
protected bool IsActive; // 受保护字段
internal DateTime DateOfBirth; // 内部字段
public const double GRAVITY = 9.81; // 常量字段
public static int Population; // 静态字段
public Person(string name, int age, bool isActive, DateTime dateOfBirth)
{
Name = name;
this.age = age;
IsActive = isActive;
DateOfBirth = dateOfBirth;
}
}
在这个例子中,Person
类有多个字段,包括公共字段、私有字段、受保护字段、内部字段、常量字段和静态字段。
字段的访问:
- 公共字段:可以在类的任何地方被访问。
- 私有字段:只能在声明它的类内部被访问。
- 受保护字段:可以在声明它的类及其子类中被访问。
- 内部字段:可以在同一个程序集内部被访问。
注意事项:
-
封装性:通常建议使用属性(Property)来访问字段,而不是直接访问字段,以保持更好的封装性和提供设置字段值时的额外逻辑处理。
-
线程安全:静态字段因为是共享的,所以在多线程环境中需要特别注意线程安全问题。
-
性能:访问字段通常比访问属性快,因为属性可能包含额外的逻辑。
7.6.2 字段的声明
在C#中,字段的声明是类或结构体定义中非常重要的部分。字段用于存储数据,可以是简单的数据类型,如整数或字符串,也可以是更复杂的数据类型,如数组或自定义类型的实例。
字段声明的基本语法:
[access-modifier] [type] field-name;
- access-modifier:访问修饰符,定义了字段的可访问性。可以是
public
、private
、protected
、internal
或它们的组合(如protected internal
)。 - type:字段的数据类型。
- field-name:字段的名称。
示例:
public class Person
{
public string Name; // 公共字段
private int age; // 私有字段
protected bool IsActive; // 受保护字段
internal DateTime DateOfBirth; // 内部字段
public const double Gravity = 9.81; // 公共常量字段
public static int Population; // 公共静态字段
}
字段的类型:
- 值类型:如
int
、float
、double
、bool
、char
、struct
等。 - 引用类型:如
string
、class
、object
等。 - 数组类型:如
int[]
、string[]
等。 - 集合类型:如
List<int>
、Dictionary<string, int>
等。
字段的修饰符:
- public:字段可以在任何地方被访问。
- private:字段只能在声明它的类内部被访问。
- protected:字段可以在声明它的类及其子类中被访问。
- internal:字段可以在同一个程序集内部被访问。
- static:字段是静态的,属于类而不是类的实例。
常量字段:
常量字段使用 const
关键字声明,一旦赋值后不能被修改。
静态字段:
静态字段使用 static
关键字声明,它们属于类本身而不是类的任何特定实例。
初始化字段:
字段可以在声明时初始化:
public class Person
{
public string Name = "Default Name";
private int age = 0;
}
注意事项:
- 封装性:通常建议使用属性(Property)来访问和修改字段,而不是直接访问字段。这样可以在设置或获取值时添加逻辑,如验证或事件触发。
- 线程安全:静态字段在多线程环境中可能会被多个线程共享,需要特别注意线程安全问题。
- 性能:直接访问字段比访问属性更快,因为属性可能包含额外的逻辑。
7.6.3 属性的概念及用途
在C#中,属性(Property)是一种使字段的访问更加灵活和受控的机制。属性允许你提供对字段的受控访问,同时保持数据封装。通过属性,你可以在读取或写入字段值时执行额外的逻辑。
属性的组成部分:
- get访问器:用于获取属性值的方法。
- set访问器:用于设置属性值的方法。
属性的声明:
属性的声明包括属性的访问修饰符、数据类型和名称,以及可选的 get
和 set
访问器。
[access-modifier] [type] PropertyName
{
get { return [field]; }
set { [field] = value; }
}
- access-modifier:访问修饰符,如
public
、private
等。 - type:属性的数据类型。
- PropertyName:属性的名称。
- field:属性背后的字段。
示例:
public class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
在这个例子中,Name
是一个公共属性,它背后有一个私有字段 name
。通过 get
和 set
访问器,外部代码可以安全地读取和修改 name
字段的值。
自动实现的属性:
C# 3.0 引入了自动实现的属性,使得你可以在不显式声明后台字段的情况下创建属性。
public class Person
{
public string Name { get; set; }
}
在这个例子中,编译器会自动生成一个私有字段来存储 Name
属性的值。
属性的封装性:
属性允许你在读取或设置字段值时添加逻辑,例如:
- 验证:在
set
访问器中验证属性值。 - 通知:在属性值改变时通知其他部分的代码(例如,通过事件)。
- 计算值:属性值可以根据其他字段或复杂计算动态计算。
示例:
public class Person
{
private string name;
public string Name
{
get { return name; }
set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Name cannot be empty.");
}
name = value;
}
}
}
在这个例子中,Name
属性的 set
访问器包含了验证逻辑,确保名称不为空。
注意事项:
- 性能:属性访问可能比直接访问字段稍慢,因为属性访问涉及方法调用。
- 简洁性:自动实现的属性提供了一种简洁的方式来声明和实现属性。
- 背靠背字段:对于自动实现的属性,编译器生成的后台字段是私有的,你不能直接访问它们。
7.6.4 属性的声明及使用
在C#中,属性(Property)是类或结构体的成员,它们提供了一种安全的访问类中字段的方法。属性可以看作是字段的公共接口,允许你控制字段的访问方式。
属性的声明
属性通常包含两个部分:get
访问器和 set
访问器,分别用于读取和设置属性值。
[access-modifier] type PropertyName
{
get { return field; }
set { field = value; }
}
- access-modifier:访问修饰符,可以是
public
、private
、protected
、internal
等。 - type:属性的类型。
- PropertyName:属性的名称。
- field:属性关联的字段。
示例
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
在这个例子中,Name
是一个公共属性,它背后有一个私有字段 _name
。
自动实现的属性
C# 3.0 引入了自动实现的属性,使得属性的声明更加简洁。
public class Person
{
public string Name { get; set; }
}
在这个例子中,编译器会自动生成一个私有字段来存储 Name
属性的值。
属性的使用
属性可以像字段一样使用,但它们提供了额外的灵活性和安全性。
Person person = new Person();
person.Name = "Alice"; // 使用属性的 set 访问器
string name = person.Name; // 使用属性的 get 访问器
属性的封装性
属性允许你在访问字段时添加逻辑,例如验证、通知或计算值。
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Name cannot be empty.");
}
_name = value;
}
}
}
在这个例子中,如果尝试设置一个空的名称,属性的 set
访问器会抛出一个异常。
只读和只写属性
属性可以只有 get
访问器(只读属性),或者只有 set
访问器(只写属性)。
public class Person
{
private string _name;
public string Name
{
get { return _name; }
}
// 只读属性
public int Age
{
set { _age = value; }
}
// 只写属性
}
注意事项
- 属性可以提高代码的可读性和封装性。
- 属性访问可能比直接访问字段稍微慢一些,因为属性访问涉及方法调用。
- 使用自动实现的属性时,不能直接访问关联的私有字段,因为它们是由编译器自动生成的。