当前位置: 首页 > news >正文

C# 语言入门(六)运算符重载、接口、预处理、异常、特性

本篇核心知识点:运算符重载、接口 interface、抽象类与接口核心区别、命名空间 namespace、预处理指令 (#define/#if/#endif 等)、正则表达式 Regex、异常处理 try-catch-finally-throw、自定义异常、装箱拆箱、特性 Attribute 基础

一、运算符重载

1. 概念

自定义类 / 结构体原本无法直接使用+ - * / == !=等运算符,通过operator关键字重载运算符,自定义运算逻辑,简化代码,替代冗余Add/Sub成员方法。

2. 核心规则

  1. 语法:public static 返回类型 operator 运算符(参数列表),二元运算符需两个参数;

  2. 只能重载 C# 允许的运算符,禁止重载. ?: :: sizeof

  3. 相等==与不等!=必须成对重载,否则编译警告;

  4. 浮点数值判等不能直接用==,需判断差值极小阈值;

  5. 不改变运算符优先级、结合性、操作数数量。

3. 代码示例:二维向量 Point

class Point{ public float X, Y; public Point(float x = 0, float y = 0){ X = x; Y = y; } // 重载 + 向量相加 public static Point operator +(Point p1, Point p2) { return new Point(p1.X + p2.X, p1.Y + p2.Y); } // 重载 - 向量相减 public static Point operator -(Point p1, Point p2){ return new Point(p1.X - p2.X, p1.Y - p2.Y); } // 重载 == 相等判断(浮点容错) public static bool operator ==(Point p1, Point p2){ float eps = 1e-6f; return Math.Abs(p1.X - p2.X) < eps && Math.Abs(p1.Y - p2.Y) < eps; } // 成对重载 != public static bool operator !=(Point p1, Point p2){ return !(p1 == p2); } public void Print(){ Console.WriteLine($"X:{X}, Y:{Y}"); } } // 测试 static void Main(){ Point a = new Point(2, 3); Point b = new Point(1, 1); Point c = a + b; c.Print(); Console.WriteLine(a != b); }

4. 拓展

1 向量

数字、向量

向量均可分别重载;

2 class 默认==比较堆内存地址,重载后实现值对比;

3 TS 无运算符重载,C++/C# 支持,游戏 Vector2/3 大量使用。

二、接口 interface

1. 概念

接口是一套行为规范契约,仅声明方法 / 属性,无实现;类 / 结构体实现接口,必须完整实现所有接口成员,用于多行为统一约束。

2. 核心特性

  1. 接口所有成员默认且只能是 public,不能写访问修饰符;

  2. 只能包含声明(方法、属性、事件),无字段、无构造函数;

  3. 不能实例化,仅能被子类实现;

  4. C# 类单继承(仅一个父类),但可同时实现多个接口,弥补多继承缺失;

  5. 接口之间可多继承;

  6. 抽象类可写实现代码,接口全部为抽象无实现。

3. 抽象类 vs 接口(核心对比)

对比维度abstract 抽象类interface 接口
成员实现可包含已实现普通方法、抽象方法全部只有声明,无任何实现
构造函数可写构造函数无构造函数
继承规则类只能继承一个抽象父类一个类可实现 N 个接口
成员权限public/protected/private 均可强制全部 public
字段可定义成员变量不允许定义字段
使用场景同类事物公共逻辑复用不同事物统一行为标准(如点击、受伤)

4. 代码示例

// 定义两个行为接口 interface IHit{ void TakeDamage(int atk); // 受伤害 } interface IAnim{ void PlayIdle(); // 播放待机动画 } // 植物类同时实现两个接口 class SunFlower : IHit, IAnim{ private int hp = 100; // 实现接口受伤害方法 public void TakeDamage(int atk){ hp -= atk; Console.WriteLine("向日葵受伤"); } // 实现动画接口 public void PlayIdle(){ Console.WriteLine("播放向日葵待机动画"); } static void Main(){ IHit plant = new SunFlower(); plant.Take(10); // 仅能调用接口定义方法 }

5. 实战拓展(Unity/Cocos)

UI 点击、拖拽、碰撞统一使用接口;引擎回调全部基于接口,只关心对象是否具备对应行为,不关心具体类型。

三、命名空间 namespace

1. 概念

相当于代码文件夹,隔离同名类,解决多文件、多库类名冲突问题。

2. 特性

  1. 语法:namespace 名称 { 所有类/结构体 }

  2. 访问方式:命名空间.类名

  3. using 命名空间;简写,无需完整路径;

  4. 支持多层嵌套(文件夹嵌套);

  5. 不同命名空间下同名类属于完全不同类型。

3. 代码示例

namespace Lesson7{ class Point { public int X; } } namespace Lesson8{ class Point { public float X; } } static void Main(){ // 完整路径区分同名类 Lesson7.Point p1 = new Lesson7(); Lesson8.Point p2 = new Lesson8(); }

拓展

Unity 大量命名空间区分引擎模块,冲突时必须写完整命名空间限定。

四、预处理指令 #define / #if / #endif

1. 概念

编译前执行的标记指令,不生成变量,仅定义符号,用于跨平台、Debug/Release 代码区分。

2. 核心指令

  1. #define 符号名:定义编译标记,必须放在文件最顶部;

  2. #if / #elif / #else / #endif:判断标记是否存在,不存在代码直接不参与编译;

  3. #undef:取消已定义标记;

  4. #warning / #error:编译时抛出警告 / 错误;

  5. #region / #endregion:代码折叠块。

3. 特性

  1. C# 预处理无 C++ 宏替换功能,仅做条件编译判断;

  2. 系统自带内置标记DEBUG(调试模式自动定义);

  3. 未定义符号区间代码灰色,编译直接忽略,不报错。

4 跨平台实战代码

#define IOS // 定义IOS平台标记 static void GameInit() { #if IOS Console.WriteLine("IOS平台初始化"); #elif ANDROID Console.WriteLine("安卓平台初始化"); #else Console.WriteLine("Windows通用逻辑"); #endif }

拓展

游戏跨平台生命周期、SDK 适配全部使用预处理区分;Release 模式DEBUG标记自动消失。

五、正则表达式 Regex

1. 概念

用于文本匹配、提取、校验字符串的规则模板,C# 内置System.Text.RegularExpressions.Regex类实现。

2. 常用元字符

\d数字 0-9;\D非数字

\w字母数字下划线;\b单词边界

+至少 1 次;*0 或多次;?0 或 1 次

{n}精准匹配 n 次;[]字符集

3. 基础代码示例(提取数字)

using System.Text.RegularExpressions; static void TestRegex() { string str = "编号995 分数05"; // 匹配连续两位数字 Regex reg = new Regex(@"\d{2}"); MatchCollection mc = reg.Matches(str); foreach(Match m in mc) { Console.WriteLine(m.Value); } }

实战场景

账号校验、配置文本解析、日志关键字提取。

六、异常处理 try-catch-finally-throw

1. 核心概念

程序运行错误称为异常,若不捕获会直接程序崩溃;通过try监控危险代码,catch捕获处理,finally无论是否异常必执行,throw主动抛出异常。

2 关键字分工

  1. try:包裹可能报错的代码块;

  2. catch(异常类型 ex):捕获对应异常,可获取异常信息ex.Message

  3. finally:无论正常 / 异常,代码一定会执行(释放资源专用);

  4. throw new Exception("提示"):手动抛出异常,向上层传递。

3. 基础示例(除数为零异常)

static float Div(float a, float b) { if (b == 0){ // 主动抛出异常 throw new Exception("除数不能为0"); } return a / b; } static void Calc(){ float res = 0; try { res = Div(10, 0); } catch(Exception ex){ Console.WriteLine("捕获异常:" + ex.Message); res = -1; // 异常默认值 } finally{ Console.WriteLine("计算结束,释放临时资源"); } Console.WriteLine("结果:" + res); }

4. 自定义异常

概念

继承Exception自定义异常类,区分不同错误类型,精准分类捕获处理。

// 数组下限越界异常 class IndexLowException : Exception{ public IndexLowException(string msg) : base(msg) { } } // 数组上限越界异常 class IndexHighException : Exception{ public IndexHighException(string msg) : base(msg) { } } static void SetArr(int[] arr, int idx, int val){ if(idx < 0) throw new IndexLowException("下标小于0"); if(idx >= arr.Length) throw new IndexHighException("下标超出数组长度"); arr[idx] = val; } // 分层捕获 static void TestArr(){ int[] data = new int[5]; try{ SetArr(data, 8, 99); } catch(IndexLowException ex){ Console.WriteLine("下限错误:"+ex.Message); } catch(IndexHighException ex){ Console.WriteLine("上限错误:"+ex.Message); } }

拓展

1 无法处理的异常可再次throw向上抛给上层调用者;

2 文件、网络、数据库资源释放写在finally,保证资源关闭。

七、装箱 & 拆箱

1. 装箱(隐式)

值类型 → object 引用类型,栈数据拷贝到堆,自动完成。

int num = 10; object obj = num; // 装箱

2. 拆箱(显式强制转换)

堆 object 转回栈值类型,必须强制转换,类型不匹配抛异常。

int res = (int)obj; // 拆箱

特性

频繁装箱拆箱产生大量堆临时对象,GC 压力大,高性能游戏尽量避免。

八、特性 Attribute(基础)

1. 概念

附加在类 / 方法 / 属性上的元数据标记,不影响程序运行,用于编译器提示、反射读取配置信息。

2. 系统内置常用特性

  1. [Obsolete("提示文本", true)]标记弃用 API,true 编译报错,false 仅警告;

  2. [Conditional("DEBUG")]条件编译,仅定义标记时方法生效。

3. 自定义特性

继承Attribute实现自定义标记,存储开发备注、Bug 记录等元数据,通过反射读取。

代码示例(弃用特性)

[Obsolete("该方法已废弃,请使用CalcNew()", false)] static void OldCalc(){ Console.WriteLine("旧计算逻辑"); }

九、反射前置

1. 概念

通过字符串类型名动态获取类、方法、属性信息,运行时创建对象、调用函数,依赖特性读取元数据。

核心 API

  1. typeof(类)获取类型Type对象;

  2. Type.GetMethods()获取所有方法;

  3. Type.GetCustomAttributes()读取附加特性。

拓展

游戏热更新、配置表解析、框架插件系统底层全部基于反射。

十、拓展

1 接口与抽象类核心区分,多接口实现作用;

2 预处理指令作用,Debug/Release 区分原理;

3 异常三层结构 try-catch-finally 使用场景,自定义异常优势;

4 运算符重载成对规则、浮点判等坑;

5 特性本质元数据,反射读取流程;

6 装箱拆箱性能缺陷优化方案。

http://www.jsqmd.com/news/1107228/

相关文章:

  • API版本管理与兼容性
  • 后端接口XSS防御全链路实战:从输入验证到CSP的纵深防护
  • 电动汽车革命:从出行工具到智能能源网
  • 混合Astar运动规划算法 路径规划和路径跟踪 MPC算法 LQR算法 PID算法
  • 5G网络优化工程师完整工作日常:从早9点到晚6点都在干什么
  • BASE理论开发实践
  • Codex 设置功能详解
  • DDD限界上下文详解
  • MES系统对制造工艺的作用研究报告
  • Apache服务器部署指南
  • .深度学习推理优化全流程:TensorRT、ONNX Runtime与模型量化部署
  • C++内存池设计实践
  • 计算机毕业设计之jsp健身房管理系统
  • 诗韵千年,风雅长存
  • 开源AI实操路线图:6个本地可运行的工业级项目
  • Figma AI原型插件与网页端:专业设计UI生成工具2026
  • 用AI控制AI:数据偏见阻断的工程化实践
  • 飞书Aily全功能实操操作手册
  • League Akari英雄联盟工具包:从新手到高手的完整使用指南
  • C++项目架构设计指南
  • C++网络通信开发教程
  • STM32与Si4731数字调频接收芯片开发实战
  • 如何高效使用MAA明日方舟智能辅助工具:5分钟快速上手完整指南
  • YouTube实时厌恶预测:多源信号融合的工程实践
  • curl命令开发实践
  • 自媒体BGM解决方案:AI音乐生成与高效剪辑技巧
  • 安全触边安装要注意啥才能避免后期故障
  • 免费解锁Microsoft 365完整功能的终极指南:Ohook激活工具详解
  • 从血管到培养皿:云克隆主动脉平滑肌细胞(ASMC)全系列上线,为心血管研究搭建跨物种细胞平台
  • MC6470 IMU与PIC18LF46K42的硬件集成与姿态控制实战