C#常识篇(三)
内置类型字节大小
以下是 C# 中常见内置数据类型的字节大小:
bool(布尔)类型:始终为 1 字节。
byte(无符号字节)类型:始终为 1 字节。
sbyte(有符号字节)类型:始终为 1 字节。
char(Unicode 字符)类型:通常为 2 字节。
short(短整型)类型:通常为 2 字节。
ushort(无符号短整型)类型:通常为 2 字节。
int(整型)类型:通常为 4 字节。
uint(无符号整型)类型:通常为 4 字节。
long(长整型)类型:通常为 8 字节。
ulong(无符号长整型)类型:通常为 8 字节。
float(单精度浮点型)类型:通常为 4 字节。
double(双精度浮点型)类型:通常为 8 字节。
decimal(高精度十进制型)类型:通常为 16 字节。
using语句
using语句用于正确使用可释放对象(实现IDisposable接口),using语句块中无论是否发生异常都会释放可释放对象。using语句可声明多个可释放对象,释放将按照声明的相反顺序进行。常见的文件I/O操作可以使用using语句。
装箱和取消装箱
装箱是将值类型转换为 object 类型或由此值类型实现的任何接口类型的过程。 常见语言运行时 (CLR) 对值类型进行装箱时,会将值包装在 System.Object 实例中并将其存储在托管堆中。 取消装箱将从对象中提取值类型。 装箱是隐式的;取消装箱是显式的。
静态存储区和托管堆的区别
静态存储区(Static Storage Area)和托管堆(Managed Heap)是两个与内存管理相关的概念,通常用于描述不同的内存分配和管理方式。
静态存储区:静态存储区是指用于存储静态变量的内存区域。静态变量是在程序编译时就被分配内存,并在整个程序生命周期内都存在的变量。这些变量通常包括全局变量、静态类成员变量以及静态局部变量。静态存储区的生命周期与程序的生命周期相同,在程序启动时被分配内存,在程序结束时释放内存。
托管堆:托管堆是托管语言(例如C#、Java等)中用于存储动态分配的对象的内存区域。在C#中,所有的类实例都是在托管堆上分配的。与静态存储区不同,托管堆上的对象的生命周期不是固定的,它们会在不再被引用时由垃圾回收器进行回收。
总结:虽然它们都是用于存储数据的内存区域,但是它们所存储的数据类型和生命周期是不同的,因此静态存储区和托管堆在内存管理中扮演不同的角色。
特性 静态存储区 托管堆 存储内容 静态变量、类型元数据、常量 对象实例、数组、字符串 生命周期 应用程序域生命周期 对象引用生命周期 管理方式 手动管理(需要显式清理) 自动垃圾回收 分配时机 类型加载时 运行时动态分配 访问方式 直接通过类型访问 通过对象引用访问 性能特点 访问快,无GC压力 访问稍慢,受GC影响 内存泄漏 容易发生(需手动管理) 较少发生(自动管理) 使用场景 全局配置、缓存、单例 业务对象、临时数据、集合
输入流和输出流
输入流(Input Stream)和输出流(Output Stream)是在计算机编程中常用的概念,用于处理数据流的读取和写入。
输入流:
1.输入流用于从数据源(如文件、网络连接、键盘输入等)读取数据。
2.输入流的主要任务是从外部数据源读取数据并提供给程序使用。
3.输入流通常提供一系列的读取方法,例如读取一个字节、读取一段字节数组、读取一个字符等。
示例:从文件中读取数据、从网络连接中接收数据等。
输出流:
1.输出流用于向目标位置(如文件、网络连接、屏幕显示等)写入数据。
2.输出流的主要任务是将程序中的数据写入到外部目标位置。
3.输出流通常提供一系列的写入方法,例如写入一个字节、写入一段字节数组、写入一个字符等。
示例:向文件中写入数据、向网络连接发送数据等。
总结:在许多编程语言中,包括Java、C#、Python等,都提供了用于处理输入流和输出流的相关类库或模块。通过使用这些类库或模块,程序可以方便地与外部数据源进行交互,实现数据的读取和写入操作。输入流和输出流的概念在各种应用场景中都有着广泛的应用,如文件处理、网络通信、数据传输等。
继承中方法的重写
(1)派生类可以重写的基类方法
1.基类中使用virtual关键字进行限定的方法(简称“虚方法”);
2.在派生类中使用new关键字对与基类同名的方法进行重写(简称“隐藏方法”);
3.基类是抽象类,抽象类中使用abstract关键字进行限定的方法(简称“抽象方法”)。
(2)virtual关键字详解
virtual关键字用于定义虚方法,基类中的virtual方法可以被直接或间接派生类选择性重写。
(3)new关键字详解
new关键字用于隐藏方法,这里的隐藏是派生类对基类隐藏同名方法,其在编译时根据声明类型决定的,这不同于重写的方法。直观的区别就在于声明为基类而实例化为派生类的对象将无法调用派生类的隐藏方法,但是声明与实例化均为派生类的对象则可以调用派生类的隐藏方法。
(4)abstract关键字详解
abstract关键字用于声明抽象类和抽象方法,且抽象方法仅存在于抽象类中,直接派生类被要求必须完成基类中抽象方法的定义,除非直接派生类也为抽象类。
(5)seald关键字详解
seald关键字用于声明密封类和密封方法,密封类无法被继承,密封方法无法被重写。
readonly关键字
readonly关键字通常用于字段和结构体。
(1)readonly修饰的字段只能在声明时或其所在类的构造函数中进行初始化,readonly修饰的结构体中所有字段都是隐式地被readonly限定;
(2)readonly修饰的字段可能是值类型也可能是引用类型,若为值类型,那么则为不可变对象,若为引用类型,则只能保证当前字段所指向的实例不变,但无法保证实例内部的状态不变,且官方不建议使用readonly修饰可变引用类型的字段,特别是对于向外公开的可变引用类型,因为这可能存在安全漏洞。
static关键字
static关键字可用于修饰类、字段、属性、方法、运算符、事件和构造函数。
(1)static修饰类:静态类的字段、属性和其它成员必须都是静态的。
(2)static修饰字段:外部访问范围将不限于某个实例对象而是整个类,通常以"类名.字段名"的方式进行访问,在类的内部将作为所有实例对象的共享字段。
(3)static修饰属性:与static字段相似,不同的是属性可以控制get和set权限。
(4)static修饰方法:外部访问范围将不限于某个实例对象而是整个类,通常以"类名.方法名"的方式进行访问,在类的内部将作为所有实例对象的共享方法。
(5)static构造函数:对于接口、类和静态类都具有静态构造函数。
索引器
索引器与属性类似,只不过属性通常针对字段,而索引器针对整个类或结构体。通过索引器可以自定义类似于数组下标访问、字典键值访问的规则,尤其是对于一些自定义的数据结构,创建索引器可以使得访问和修改更加便捷。属性的各种用法均适用于索引器,除了"自动实现属性"的用法,索引器可以指定多个参数。
运算符重载
运算符重载与函数重载类似,通过对某个类或结构体的可重载运算符进行重载,使得该类或结构体的实例在运算符表达式中按照重载的逻辑进行操作,运算符重载与函数重载一样具备编译时自动匹配的特性。值得注意的是运算符重载需要明确可重载运算符以及成对重载的运算符,运算符重载的参数至少有一个类型包含当前类。
如果这篇文章对你有帮助,请给作者点个赞吧!
浙公网安备 33010602011771号