C# 属性完全指南:访问器、自动属性、只读属性与抽象属性
属性是类、结构体、接口的命名成员。成员变量或方法称为字段。属性是字段的扩展,使用相同语法访问。它们通过访问器读取、写入或计算私有字段值。
属性不命名存储位置,而是有访问器获取、设置或计算值。
访问器
属性的访问器包含获取(读取/计算)或设置(写入)属性的可执行语句。可包含 get 访问器、set 访问器或两者皆有。
完整属性示例
// Code 属性
public string Code {
get { return code; }
set { code = value; }
}
// Name 属性
public string Name {
get { return name; }
set { name = value; }
}
// Age 属性
public int Age {
get { return age; }
set { age = value; }
}
完整示例
using System;
namespace tutorialspoint {
class Student {
private string code = "N.A";
private string name = "not known";
private int age = 0;
public string Code {
get { return code; }
set { code = value; }
}
public string Name {
get { return name; }
set { name = value; }
}
public int Age {
get { return age; }
set { age = value; }
}
public override string ToString() {
return "Code = " + Code + ", Name = " + Name + ", Age = " + Age;
}
}
class ExampleDemo {
public static void Main() {
Student s = new Student();
s.Code = "001";
s.Name = "Zara";
s.Age = 9;
Console.WriteLine("Student Info: {0}", s); // Code = 001, Name = Zara, Age = 9
s.Age += 1;
Console.WriteLine("Student Info: {0}", s); // Code = 001, Name = Zara, Age = 10
Console.ReadKey();
}
}
}
自动实现属性
C# 3.0+ 支持自动属性,编译器自动生成后备字段:
public string Name { get; set; }
public int Age { get; set; }
等价于手写后备字段 + get/set。仅用于简单封装,需逻辑时用完整属性。
只读/只写属性
- 只读:仅有
get(C# 6+ 可用=>表达式体) - 只写:仅有
set(罕见)
// 只读属性(C# 6+ 表达式体)
public string FullName => $"{FirstName} {LastName}";
// 传统只读
public string FullName { get { return $"{FirstName} {LastName}"; } }
// 初始化后只读
public string Id { get; init; } // C# 9+ init 访问器,仅构造/对象初始化器可设置
属性访问器访问级别
可为 get/set 单独指定访问修饰符(比属性本身更严格):
public string Name { get; private set; } // 外部可读,仅内部可写
internal int Age { get; set; } // 程序集内可读写
抽象属性
抽象类可包含抽象属性,派生类必须实现:
public abstract class Person {
public abstract string Name { get; set; }
public abstract int Age { get; set; }
}
class Student : Person {
private string name = "N.A";
private int age = 0;
public override string Name {
get { return name; }
set { name = value; }
}
public override int Age {
get { return age; }
set { age = value; }
}
}
属性 vs 字段
| 特性 | 字段 | 属性 |
|---|---|---|
| 语法 | public int Age; | public int Age { get; set; } |
| 封装性 | 无(直接访问) | 可控(验证、计算、日志) |
| 接口中 | 不可声明 | 可声明 |
| 数据绑定 | 不支持 | 支持 |
| 二进制兼容 | 修改破坏兼容 | 可改实现不破坏兼容 |
| 调试断点 | 不可在赋值处断点 | 可在 set 断点 |
最佳实践
- 公共 API 暴露属性而非字段
- 简单封装用自动属性
- 验证逻辑放在
set中 - 计算型属性仅用
get,避免昂贵计算(或缓存结果) - 不可变类型用
init或只读属性 - 避免在属性中做耗时操作(I/O、网络),改用方法明确语义
C语言
- 算术性质:结合律、交换律与分配律详解
- 指数法则:代数运算关键性质
- 银的抗菌力量:金属如何对抗细菌、真菌和病毒
- AMPCO® 25 锻件:高性能模具材料合金
- UGICHROM® 4462:高性能微裂纹铬镀层,用于液压气动系统
- UGICHROM® 4362 — 液压气动用优质微裂纹铬镀不锈钢
- Bainidur® 1300:低裂纹风险、高强度锻造合金
- Bainidur® 7980 CN:优质低合金钢,渗碳碳氮共渗性能卓越
- UGICHROM® 4460 - 超耐用铬镀不锈钢液压气动杆
- Printdur® 4404 (316L) 增材制造专用不锈钢粉末
- VDM® Alloy 40 B 合金 —— 高性价比发热元件合金
- 钼铪碳合金 (MHC)——高温颗粒强化合金