类的基本结构
public class Person
{
// 字段(field)
private string _name;
private int _age;
// 构造函数
public Person(string name, int age)
{
_name = name;
_age = age;
}
// 方法
public void Greet()
{
Console.WriteLine($"Hi, I'm {_name}, {_age} years old.");
}
}
// 用
var p = new Person("Alice", 30);
p.Greet();
属性(property):用语义代替 get/set 方法
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("Name 不能空");
_name = value;
}
}
}
var p = new Person();
p.Name = "Alice"; // 调用 setter
Console.WriteLine(p.Name); // 调用 getter
value 是 setter 中默认的新值参数。
自动属性(最常用)
字段 + get/set 完全模板化时——一句话写完:
public class Person
{
public string Name { get; set; } = "";
public int Age { get; set; }
}
编译器自动生成隐藏字段 + get/set。
只读属性
public class Circle
{
public double Radius { get; } // 只读
public double Area => Math.PI * Radius * Radius; // 表达式体
public Circle(double r) => Radius = r;
}
{ get; } 只能在构造函数里赋值。
init-only(C# 9+)
public class Point
{
public int X { get; init; }
public int Y { get; init; }
}
var p = new Point { X = 1, Y = 2 }; // 对象初始化器
p.X = 99; // ❌ 报错:init 后不能再改
init 接受对象创建期间赋值(构造函数 + 对象初始化器),之后只读。
required(C# 11+)
public class User
{
public required string Name { get; init; }
public required string Email { get; init; }
public int Age { get; init; } // 可选
}
var u = new User { Name = "A", Email = "a@x.com" }; // ✅
var u2 = new User { Name = "A" }; // ❌ 编译错误:缺 Email
required 强制使用对象初始化器时必须设置——比抛 ArgumentNull 更早发现错误。
主构造函数(C# 12+)
public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
public void Greet() => Console.WriteLine($"Hi {Name}");
}
var p = new Person("Alice", 30);
类声明里直接列参数——它们成为构造参数 + 类作用域内可见的"伪字段"。简化样板代码。
静态成员
public class Counter
{
private static int _total = 0;
public static int Total => _total;
public Counter() { _total++; }
}
new Counter(); new Counter();
Console.WriteLine(Counter.Total); // 2
静态成员属于类,不属于任何实例。所有实例共享。
静态构造函数
public class Config
{
public static readonly string Path;
static Config()
{
Path = Environment.GetEnvironmentVariable("CONFIG_PATH") ?? "./config.json";
}
}
第一次访问类的任何静态成员时执行一次——线程安全。
readonly 字段
public class Order
{
public readonly DateTime CreatedAt; // 字段只能在构造里赋值
public Order() { CreatedAt = DateTime.UtcNow; }
}
readonly 字段 vs 只读自动属性 { get; }:行为相似,属性更主流——除非有特殊性能 / API 兼容理由。
访问修饰符
| 谁能访问 | |
|---|---|
public |
任何代码 |
private(默认) |
本类 |
protected |
本类 + 子类 |
internal |
本程序集 |
protected internal |
子类 或 本程序集 |
private protected(C# 7.2+) |
子类 且 本程序集 |
file(C# 11+) |
本文件 |
默认 private——除非有理由公开,否则保持。
对象初始化器
public class Address
{
public string City { get; set; } = "";
public string Zip { get; set; } = "";
}
var addr = new Address
{
City = "Beijing",
Zip = "100000",
};
// 等价于
var addr2 = new Address();
addr2.City = "Beijing";
addr2.Zip = "100000";
可以嵌套 + 初始化集合:
var person = new Person
{
Name = "Alice",
Addresses = { new Address { City = "X" }, new Address { City = "Y" } },
};
this
public class Box
{
public int Width;
public Box(int width)
{
this.Width = width; // this. 区分参数和字段
}
}
this 指当前实例——必要时显式(同名时);其他时候可省。
部分类(partial class)
// File1.cs
public partial class Form
{
public void Init() { ... }
}
// File2.cs
public partial class Form
{
public void Render() { ... }
}
跨文件拆同一个类。代码生成器(如 WinForms、source generators)大量用。
→ 下一篇 继承与多态