C# 面向对象写法速查手册

2 min入门

C# 面向对象编程 的完整教学讲解。

类的定义

基本写法:私有字段声明 private <类型> <字段名>;

// 声明类内部私有字段
private string _name;
private int _age;

基本写法:带验证的属性 public <类型> <属性名> { get => <字段>; set => <赋值表达式>; }

// 属性设置时进行参数验证
public string Name
{
    get => _name;
    set => _name = value ?? throw new ArgumentNullException(nameof(value));
}

基本写法:自动属性 public <类型> <属性名> { get; set; } = <默认值>;

// 自动实现的属性带默认值
public string Email { get; set; } = string.Empty;

基本写法:init 属性 public <类型> <属性名> { get; init; } = <默认值>;

// 仅初始化时赋值的属性
public string Address { get; init; } = string.Empty;

基本写法:计算属性 public <类型> <属性名> => <表达式>;

// 基于其他属性计算的只读属性
public bool IsAdult => Age >= 18;

基本写法:构造函数 public <类名>(<参数>) { <赋值语句>; }

// 类的构造函数初始化字段
public Person(string name, int age)
{
    _name = name;
    _age = age;
}

基本写法:方法重载 public <返回类型> <方法名>() => <表达式>;

// 无参数的方法重载
public string Greet() => $"你好,我是{Name}";

基本写法:带参数方法重载 public <返回类型> <方法名>(<参数>) => <表达式>;

// 带参数的方法重载
public string Greet(string greeting) => $"{greeting},我是{Name}";

单行写法:对象初始化器 var <变量> = new <类型>(<参数>) { <属性> = <值> };

// 单行使用构造函数和对象初始化器
var person = new Person("张三", 25) { Email = "zhangsan@example.com" };

换行写法:对象初始化器 var <变量> = new <类型>(<参数>) { <属性1> = <值1>, <属性2> = <值2> };

// 换行使用构造函数和对象初始化器
var person = new Person("张三", 25)
{
    Email = "zhangsan@example.com",
    Address = "北京市"
};

基本写法:目标类型 new <类型> <变量> = new(<参数>);

// C# 9+ 目标类型 new 表达式
Person p = new("王五", 28);

基本写法:静态字段属性 public static <类型> <属性名> { get; private set; }

// 类级别共享的静态属性
public static int InstanceCount { get; private set; }

基本写法:静态构造函数 static <类名>() { <语句>; }

// 类首次访问时执行的静态构造函数
static MathHelper()
{
    InstanceCount = 0;
}

基本写法:静态方法 public static <返回类型> <方法名>(<参数>) => <表达式>;

// 类级别的静态方法
public static double CircleArea(double radius) => Math.PI * radius * radius;

基本写法:静态类 public static class <类名> { ... }

// 静态类只能包含静态成员
public static class StringExtensions { }

基本写法:扩展方法 public static <返回类型> <方法名>(this <类型> <参数>) => <表达式>;

// 为现有类型添加扩展方法
public static bool IsNullOrEmpty(this string? str) =>
    string.IsNullOrEmpty(str);

构造函数

基本写法:构造函数链 public <类名>(<参数>) : this(<参数>) { ... }

// 调用其他构造函数
public Product(string name, decimal price, string category) : this(name, price)
{
    Category = category;
}

基本写法:主构造函数 public class <类名>(<参数>) { ... }

// C# 12 主构造函数简化构造函数定义
public class Service(ILogger logger, IConfiguration config)
{
    public void DoWork() => logger.LogInformation("执行工作...");
}

继承

基本写法:基类定义 public class <基类> { public virtual <返回类型> <方法>() => <表达式>; }

// 基类定义虚方法供子类重写
public class Animal
{
    public virtual string Speak() => $"{Name}发出了声音";
}

基本写法:派生类继承 public class <派生类> : <基类> { public <派生类>(<参数>) : base(<参数>) { ... } }

// 派生类继承基类并调用基类构造函数
public class Dog : Animal
{
    public Dog(string name, int age) : base(name, age) { }
}

基本写法:override 重写虚方法 public override <返回类型> <方法>() => <表达式>;

// 重写基类的虚方法
public override string Speak() => $"{Name}汪汪叫!";

基本写法:sealed 密封方法 public sealed <返回类型> <方法>() => <表达式>;

// 阻止子类进一步重写
public sealed string GetInfo() => $"{Name}, {Age}岁";

基本写法:new 方法隐藏 public new <返回类型> <方法>() => <表达式>;

// 隐藏基类方法(不推荐使用)
public new string GetInfo() => $"{Name} ({Breed}), {Age}岁";

基本写法:多态调用 <基类> <变量> = new <派生类>(<参数>);

// 运行时根据实际类型调用方法
Animal animal = new Dog("旺财", 3, "金毛");
Console.WriteLine(animal.Speak());

抽象类与接口

基本写法:抽象类定义 public abstract class <类名> { public abstract <返回类型> <方法>(); }

// 定义包含抽象方法的抽象类
public abstract class Shape
{
    public abstract double Area();
}

基本写法:抽象类虚方法 public virtual <返回类型> <方法>() => <表达式>;

// 抽象类中定义可选重写的虚方法
public virtual string Describe() =>
    $"{GetType().Name} (颜色: {Color}, 面积: {Area():F2})";

基本写法:实现抽象类 public class <派生类> : <抽象类> { public override <返回类型> <方法>() => <表达式>; }

// 派生类实现抽象方法
public class Circle : Shape
{
    public override double Area() => Math.PI * Radius * Radius;
}

基本写法:接口定义 public interface <接口名> { <返回类型> <方法>(); }

// 定义接口契约
public interface IReadable
{
    string Read();
}

基本写法:接口默认实现 public interface <接口名> { void <方法>(); void <默认方法>() => <表达式>; }

// C# 8+ 接口默认方法实现
public interface ILogger
{
    void Log(string message);
    void LogWarning(string message) => Log($"[WARN] {message}");
}

单行写法:多接口实现 public class <类名> : <接口1>, <接口2>, <接口3> { ... }

// 单行声明实现多个接口
public class FileStorage : IReadable, IWritable, ILogger { }

换行写法:多接口实现 public class <类名> : <接口1>, <接口2>, <接口3> { ... }

// 换行声明实现多个接口
public class FileStorage
    : IReadable, IWritable, ILogger
{
    public string Read() => File.ReadAllText(_path);
}

属性与索引器

基本写法:派生属性 get/set public <类型> <属性名> { get => <表达式>; set => <赋值表达式>; }

// 基于其他属性计算的派生属性
public double Fahrenheit
{
    get => _celsius * 9 / 5 + 32;
    set => _celsius = (value - 32) * 5 / 9;
}

基本写法:索引器定义 public <类型> this[<参数>] { get; set; }

// 通过索引访问对象成员
public double this[int row, int col]
{
    get => _data[row, col];
    set => _data[row, col] = value;
}

基本写法:索引器赋值 <对象>[<索引>] = <值>;

// 使用索引器设置值
var matrix = new Matrix(3, 3);
matrix[0, 0] = 1.0;

基本写法:索引器取值 <类型> <变量> = <对象>[<索引>];

// 使用索引器获取值
var value = matrix[2, 2];

运算符重载

基本写法:二元加法运算符重载 public static <类型> operator +(<类型> <参数1>, <类型> <参数2>)

// 重载加法运算符
public static Vector operator +(Vector a, Vector b) =>
    new(a.X + b.X, a.Y + b.Y);

基本写法:二元减法运算符重载 public static <类型> operator -(<类型> <参数1>, <类型> <参数2>)

// 重载减法运算符
public static Vector operator -(Vector a, Vector b) =>
    new(a.X - b.X, a.Y - b.Y);

基本写法:标量乘法运算符重载 public static <类型> operator *(<类型> <参数>, <标量类型> <标量>)

// 重载与标量的乘法运算符
public static Vector operator *(Vector v, double scalar) =>
    new(v.X * scalar, v.Y * scalar);

基本写法:相等运算符重载 public static bool operator ==(<类型> a, <类型> b)

// 重载相等比较运算符
public static bool operator ==(Vector a, Vector b) =>
    a.X == b.X && a.Y == b.Y;

基本写法:不等运算符重载 public static bool operator !=(<类型> a, <类型> b)

// 重载不等比较运算符(需与 == 成对重载)
public static bool operator !=(Vector a, Vector b) => !(a == b);

基本写法:Equals 重写 public override bool Equals(object? <参数>)

// 重写 Equals 方法
public override bool Equals(object? obj) =>
    obj is Vector v && this == v;

基本写法:GetHashCode 重写 public override int GetHashCode()

// 重写 GetHashCode 方法
public override int GetHashCode() => HashCode.Combine(X, Y);

基本写法:隐式转换运算符 public static implicit operator <目标类型>(<源类型> <参数>)

// 定义类型的隐式转换
public static implicit operator Vector((double x, double y) tuple) =>
    new(tuple.x, tuple.y);

记录类型 (Record)

基本写法:位置记录 public record <名称>(<参数列表>);

// 简洁的不可变数据类型定义
public record Person(string Name, int Age);

基本写法:记录继承 public record <派生>(<参数>) : <基类>(<参数>);

// 记录类型支持继承
public record Student(string Name, int Age, string School) : Person(Name, Age);

基本写法:record struct public record struct <名称>(<参数列表>);

// 值类型记录
public record struct Point(double X, double Y);

基本写法:readonly record struct public readonly record struct <名称>(<参数列表>);

// 不可变值类型记录
public readonly record struct Money(decimal Amount, string Currency);

基本写法:记录值相等性 bool <结果> = <记录1> == <记录2>;

// 记录类型基于值比较相等性
var p1 = new Person("张三", 25);
var p2 = new Person("张三", 25);
Console.WriteLine(p1 == p2);

基本写法:记录 with 表达式 var <变量> = <记录> with { <属性> = <值> };

// 非破坏性修改记录
var p3 = p1 with { Age = 26 };

基本写法:记录解构 var (<变量1>, <变量2>) = <记录>;

// 解构记录的属性
var (name, age) = p1;
Console.WriteLine($"{name}, {age}");