
简介
该用户还未填写简介
擅长的技术栈
可提供的服务
暂无可提供的服务
栈 = 快、自动释放、存值类型 / 引用指针托管堆 = 慢、GC 管理、存引用类型真实数据值类型 = 数据自己存自己引用类型 = 栈存地址,堆存数据class 里的值类型 → 存在堆上。
装箱:值类型 → 引用类型,堆分配 + 数据拷贝拆箱:引用类型 → 值类型,类型检查 + 数据拷贝回栈成本:装箱 > 拆箱 > 普通赋值优化:用泛型、避免转 object、避免频繁字符串拼接。
变量本来应该在栈上,但是因为被 “外部引用”,被迫跑到堆上,无法在栈上自动释放→ 这就叫逃逸。逃逸 = 局部变量逃离了它的局部作用域,生命周期被延长了。作用域:变量能被访问的代码范围生命周期:变量在内存中存活的时间变量逃逸:局部变量被迫从栈跑到堆,生命周期被延长逃逸危害:增加 GC 压力,降低性能核心优化:尽量让局部变量不逃逸,留在栈上。
摘要:继承允许子类复用父类成员并重写方法,多态通过父类引用调用子类实现。C#使用虚方法表(VTable)实现多态:每个类拥有独立VTable,子类复制父类VTable并替换重写方法地址。当父类引用调用虚方法时,CLR通过对象类型指针查找VTable,动态执行子类方法。virtual和override是关键,而new不参与多态。VTable机制确保运行时根据实际对象类型调用正确方法,这是多态的核心实
本文系统介绍了C#泛型的核心概念与应用。首先阐述了泛型的基础特性:通过延迟类型指定实现代码复用,确保类型安全并避免装箱拆箱。其次详细解析了泛型约束(where)的五种形式及其组合使用,包括基类、接口、引用类型等约束。重点讲解了协变(out)和逆变(in)机制,说明它们如何通过子父类转换实现类型兼容性。最后揭示了CLR底层的实现原理:引用类型共享代码而值类型独立生成,解释了泛型在性能和内存上的优势。
本文探讨C#字符串的两个核心特性:不可变性和驻留池机制。字符串不可变性指字符串创建后不能被修改,任何"修改"操作都会创建新对象,这保证了线程安全但可能导致频繁拼接时性能问题(建议使用StringBuilder)。字符串驻留池是CLR维护的全局缓存池,存储相同内容的单个实例,分为编译期自动驻留(字面量)和运行期手动驻留(string.Intern())。两者协同工作:不可变性确保
C#中struct和class的核心区别:struct是值类型,默认栈分配(局部变量在栈,作为字段/数组元素时内嵌到堆);class是引用类型,实例始终在堆上。struct通过值拷贝创建独立副本,class通过引用共享对象。struct适合小数据、高频分配场景(如坐标、配置),可避免GC开销;class适合复杂业务、需要继承多态的场景。注意struct赋值给object或接口时会触发装箱操作,导致
《C#程序运行机制解析》摘要: 本文系统讲解了C#程序的运行原理。C#代码首先被编译为IL中间语言和元数据,打包成程序集(.exe/.dll)。运行时CLR加载程序集,通过JIT编译器将IL代码即时编译为机器码执行。核心机制包括:1)程序集包含IL代码而非机器码;2)CLR作为运行时环境负责内存管理和安全检查;3)JIT编译器实现首次编译缓存优化。这种架构保证了.NET程序的跨平台性,所有语言最终
摘要:WinForm/WPF中UI控件只能由UI线程操作,子线程直接修改会抛出跨线程异常。解决方法是通过Invoke/BeginInvoke将UI更新任务交给UI线程执行。Invoke是同步调用会阻塞子线程,BeginInvoke是异步调用不阻塞。WPF中使用Dispatcher实现相同功能。文章提供了封装类简化调用流程,推荐使用BeginInvoke异步方式,并给出封装代码示例。核心原则是:UI
foreach循环本质会被编译器转换为迭代器模式,通过版本号机制确保集合遍历期间不被修改。List内部维护_version字段,任何结构性修改都会使其自增。迭代器初始化时会保存当前版本号,每次MoveNext()都会校验版本一致性,若发现不一致则抛出异常。这种设计是为了避免遍历过程中的漏项、重复或指针失效问题。文章介绍了6种安全修改集合的方法:for倒序遍历、先标记后删除、RemoveAll方法、







