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

C#中栈和堆以及修饰符

关于堆中字符串的存放

string s1="123"
string s2="123"
string s1="456"

此时s1输出为456 而s2仍然为123

因为在使用 String str = "字符串" 的方式来创建String变量的时候,那么String的值便会存储在String常量池中,在我们以这种方式创建String变量时,编译器会先判断你这个内容有没有已经在常量池出现过了,如果已经出现过,那么就不会再在常量池中使用空间来存放一个相同的内容,这个内容只会固定有一个引用,所以在创造相同内容的String的时候,他们的引用都是相同的。又有一种情况:一开始A和B内容相同,就是说s1与s2的引用都相同时,此时将s1的内容更改,那么s1的内容在常量池中就会使用另一块空间,那么相应的s1的引用也会改变,而s2的引用并不会改变,因为s2此时还是存储的原来的内容。我们可以来看简易的图解:

栈区、堆区、常量区、静态区、代码区 ,static的变量放在静态区

在C#中,内存管理是由.NET运行时(CLR - Common Language Runtime)负责的。CLR将内存分为几个不同的区域,用于存储不同类型的数据。以下是这些区域的简要说明:

  1. 栈区(Stack)

    • 栈是一种后进先出(LIFO - Last In, First Out)的数据结构。

    • 局部变量和方法调用时的参数通常存储在栈上。

    • 栈的大小是有限的,并且在线程创建时分配。

  2. 堆区(Heap)

    • 堆是用于动态内存分配的内存区域。

    • 对象通常是在堆上分配的。

    • .NET运行时的垃圾回收器负责管理堆内存,自动回收不再使用的对象。

  3. 常量区(Read-Only Data Section)

    • 常量数据存储在只读数据区,这些数据在程序的整个生命周期内都不会改变。

  4. 静态区(Static Data Section)

    • 静态变量和类变量存储在静态区。

    • 静态变量的生命周期与应用程序域的生命周期相同,它们在第一次使用时初始化,并在应用程序域卸载时销毁。

  5. 代码区(Code Section)

    • 包含编译后的程序代码,即中间语言(MSIL - Microsoft Intermediate Language)代码。

    • 代码区是只读的,存储了方法的IL代码和元数据。

  6. JIT编译后的代码

    • 虽然不是传统意义上的内存区域,但.NET运行时的JIT(Just-In-Time)编译器会将IL代码编译成本地机器代码,这些代码在执行时存储在内存中。

  7. 全局常量区

    • 有些实现可能还有一个全局常量区,用于存储全局常量。

  8. 线程局部存储(Thread Local Storage, TLS)

    • 用于存储线程特有的数据,比如线程的堆栈底和线程的异常处理上下文。

关于 static 变量,它们确实存储在静态区。每个 static 变量都属于一个类或结构,而不是类的实例。因此,它们在程序集加载时初始化,并在程序集卸载时释放。由于 static 变量与任何特定实例无关,它们在整个应用程序域中是唯一的。

修饰符介绍

在C#中,修饰符(Modifiers)用于定义类、方法、属性、字段等成员的访问级别和行为。以下是一些常用的修饰符:

  1. 访问修饰符

    • public:成员可以被任何其他代码访问。

    • private:成员只能在其定义的类内部访问。

    • protected:成员只能在其定义的类或派生类中访问。

    • internal:成员只能在同一个程序集(Assembly)中访问。

    • protected internal:成员可以在同一个程序集或派生类中访问。

  2. 非访问修饰符

    • static:表示该成员属于类本身,而不是类的实例。

    • const:表示一个常量,其值在编译时已知,并且在运行时不可更改。

    • readonly:表示一个字段可以在声明时或构造函数中被赋值,但之后不可更改。

    • abstract:用于声明抽象类或抽象方法,抽象方法必须在派生类中被重写。

    • sealed:用于阻止继承类进一步重写方法。

    • override:用于重写基类中的虚方法或属性。

    • virtual:用于声明一个方法或属性,该方法或属性可以在派生类中被重写。

    • event:用于声明事件,通常与委托一起使用。

    • new:用于隐藏继承类中的同名成员。

    • volatile:指示字段可能被多个线程同时访问,要求编译器和运行时确保对该字段的读写操作的原子性。

    • async:用于声明异步方法,允许使用 await 关键字。

    • unsafe:指示包含指针操作的代码块,只能在 unsafe 上下文中使用。

  3. 接口实现修饰符

    • 当实现接口成员时,可以使用 publicprivate 修饰符来指定实现的可访问性。

  4. 参数修饰符

    • ref:表示方法调用时传递的参数是按引用传递的。

    • out:类似于 ref,但调用者不需要在调用前初始化参数。

    • params:表示方法可以接收不定数量的参数,这些参数被封装在数组中。

  5. 特性修饰符(Attribute Modifiers):

    • 用于定义特性(Attribute)的适用范围,如 AttributeUsage

方法重载和重写

方法重载(Overloading)

方法重载是指在同一个类中可以有多个同名的方法,但它们的参数列表必须不同。参数列表的不同可以是参数的数量不同,或者是参数的类型不同。

特点

  • 方法名相同。

  • 参数列表不同(参数数量、类型、顺序)。

  • 返回类型可以相同也可以不同。

  • 重载方法在编译时进行解析。

方法重写(Overriding)

方法重写是指在派生类(子类)中重写基类中的虚方法(virtual)或抽象方法(abstract)。它允许派生类提供自己的实现方式。

特点

  • 基类方法必须被声明为 virtualabstractoverride

  • 派生类使用 override 关键字来重写方法。

  • 重写方法的访问级别不能比基类方法更严格。

  • 返回类型必须与被重写的方法一致,或者为基方法返回类型的子类型。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 系统架构设计师教程 第3章 信息系统基础知识-3.8 典型信息系统架构模型-解读
  • Kafka Producer之事务性
  • VSCode STM32嵌入式开发插件记录
  • 计算机毕业设计hadoop+spark+hive物流大数据分析平台 仓储数据分析 物流预测系统 物流信息爬虫 物流大数据 机器学习 深度学习 知识图谱 大数据
  • 软件物料清单科普 | SBOM对开源管理的意义
  • Apache POI-Excel入门与实战
  • 数据仓库中的数据治理流程
  • 什么是离线语音识别芯片?与在线语音识别的区别
  • nfs和samba
  • 服务器上使用Docker部署sonarQube,并集成到Jenkins实现自动化。
  • 网站验证:确保网络安全与信任的重要步骤
  • C2W3.Assignment.Language Models: Auto-Complete.Part1
  • 一个简单好用安全的开源交互审计系统,支持SSH,Telnet,Kubernetes协议(带私活)
  • 智慧隧道可视化:安全与效率的智能保障
  • SpringMVC实现文件上传
  • 时间复杂度分析经典问题——最大子序列和
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • angular2开源库收集
  • Docker 笔记(2):Dockerfile
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • HTTP那些事
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Invalidate和postInvalidate的区别
  • Javascript Math对象和Date对象常用方法详解
  • js作用域和this的理解
  • MySQL的数据类型
  • node和express搭建代理服务器(源码)
  • pdf文件如何在线转换为jpg图片
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • scrapy学习之路4(itemloder的使用)
  • Spring Boot MyBatis配置多种数据库
  • text-decoration与color属性
  • Windows Containers 大冒险: 容器网络
  • 安卓应用性能调试和优化经验分享
  • 大快搜索数据爬虫技术实例安装教学篇
  • 读懂package.json -- 依赖管理
  • 后端_ThinkPHP5
  • 经典排序算法及其 Java 实现
  • 力扣(LeetCode)56
  • 前言-如何学习区块链
  • 如何合理的规划jvm性能调优
  • 山寨一个 Promise
  • 数据结构java版之冒泡排序及优化
  • ionic入门之数据绑定显示-1
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 阿里云服务器购买完整流程
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • #### go map 底层结构 ####
  • #14vue3生成表单并跳转到外部地址的方式
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (附源码)ssm智慧社区管理系统 毕业设计 101635