
接口在C#中接口是一种定义契约的引用类型。它只包含方法、属性、事件或索引器的声明不包含实现。从C#8.0开始接口可以包含默认是实现比如静态或实例方法但核心依然是“定义能力而非细节”。特性接口内不能包含实例字段如int age内部没有构造和析构方法不可以实例化一个类可以实现多个接口C#8.0前所有成员默认为public在之后可以指定private、protected、static、virtual等当多个接口有同名方法时可以显式指定实现哪个。// 定义接口 public interface IAnimal { // 属性自动属性在接口中只表示必须存在 get/set string Name { get; set; } // 方法无实现体 void MakeSound(); } // 实现接口 public class Dog : IAnimal { public string Name { get; set; } public void MakeSound() { Console.WriteLine(${Name} says: Woof!); } }接口的多实现与显式实现public interface ICanFly { void Move(); } public interface ICanSwim { void Move(); } public class Duck : ICanFly, ICanSwim { // 显式实现调用时需转型为对应接口 void ICanFly.Move() Console.WriteLine(Fly); void ICanSwim.Move() Console.WriteLine(Swim); // 普通实现会同时满足两个接口但若重名会冲突通常用显式 } // 使用 Duck d new Duck(); ((ICanFly)d).Move(); // 输出 Fly ((ICanSwim)d).Move(); // 输出 SwimC#8.0后允许接口中添加带实现的方法public interface ILogger { void Log(string message); // 默认实现C# 8.0 void LogError(string error) { Log($ERROR: {error}); } } public class ConsoleLogger : ILogger { public void Log(string message) Console.WriteLine(message); // 无需实现 LogError直接继承默认实现 }枚举在C#中枚举enum是用于定义一组命名常量的值类型。它让代码更易读、更安全避免使用魔法数字或字符串。特性继承自System.Enum基类是System.ValueType默认值类型为int可以指定为byte、short、long等整数类型每个成员都对应一个整数值默认从0开始依次递增不同枚举之间是不能隐式转换的支持位运算。// 定义枚举默认从 0 开始 public enum Weekday { Sunday, // 0 Monday, // 1 Tuesday, // 2 Wednesday, // 3 Thursday, // 4 Friday, // 5 Saturday // 6 } // 手动指定值 public enum ErrorCode { Success 0, NotFound 404, ServerError 500, Timeout 408 // 可以跳号 } // 指定底层类型 public enum FileSize : long { Small 1024, Large 1048576, // 如果值超过 int 范围必须指定 long }结构体C#中结构体是一种值类型用于封装小型数据组。与类不同结构体在栈上分配赋值时复制值而非引用。特性继承自System.ValueType赋值即复制由于是在栈上分配内存所以结构体的性能更高但当占用内存过大时复制开销也大结构体是隐式密封也就是sealed类型不能继承也不能被继承但可以实现接口内部必须有有参构造函数在C#10前无参构造函数不允许被自定义在C#10前字段不能再声明时初始化。// 定义结构体 public struct Point { // 字段推荐私有通过属性访问 private int _x; private int _y; // 属性可自动属性 public int X { get; set; } public int Y { get; set; } // 构造函数必须有参数 public Point(int x, int y) { X x; Y y; } // 方法 public double DistanceTo(Point other) { return Math.Sqrt(Math.Pow(X - other.X, 2) Math.Pow(Y - other.Y, 2)); } // 重写 ToString public override string ToString() $({X}, {Y}); } // 使用 Point p1 new Point(3, 4); Point p2 p1; // 复制值修改 p2 不影响 p1 p2.X 10; Console.WriteLine(p1); // (3, 4) Console.WriteLine(p2); // (10, 4)用readonly修饰强制不可变性可以提高安全性public readonly struct ReadOnlyPoint { public int X { get; } // 只读属性 public int Y { get; } public ReadOnlyPoint(int x, int y) { X x; Y y; } // 方法必须是 readonly不会修改状态 public double DistanceTo(ReadOnlyPoint other) { return Math.Sqrt(Math.Pow(X - other.X, 2) Math.Pow(Y - other.Y, 2)); } }如果是ref struct只能分配在栈上不能装箱也不能作为类字段用于高性能场景的时候public ref struct Buffer { private Spanbyte _data; public Buffer(Spanbyte data) { _data data; } public void Fill(byte value) { _data.Fill(value); } } // 注意ref struct 不能实现接口不能装箱