![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C#
文章平均质量分 79
永恒星
这个作者很懒,什么都没留下…
展开
-
C#流Stream与IO详解(5)——读取文件的详细流程
这里说的是阻塞式读写文件,只说主要的流程,不包括每个流程中为了处理不同情况的更细节处理。原创 2023-11-21 13:53:08 · 658 阅读 · 0 评论 -
C#流Stream与IO详解(4)——如何更快的读写文件
在我们追求更快读写速度时,通常都是为了读写二进制文件,而不是文本文件,所以这里只说FileStream、BinaryReader、BinaryWriter的使用。从前文的源码解读中能看到使用BinaryReader和BinaryWriter进行IO读写时本质还是调用了FileStream的接口,所以我们这里只说FileStream的使用即可。此外,我们这里说的更快读写是指在同一个线程中的读写,而不是使用多线程读写。原创 2023-09-22 08:54:23 · 781 阅读 · 0 评论 -
C# 流Stream详解(2)——FileStream、BinaryReader、MemorySream、SreamReader等之间的关系
电脑上的文件有很多,文本文件、音频文件、视频文件等等,物理什么文件,在电脑上保存的时候本质都是一堆二进制数据,用FileStream可以读取所有的文件,用TextReader可以更好的读所有的文本类型的文件,StreamReader可以用更好的读某种编码格式的文本文件。MemoryStream用于解决在内存中各种流的交换处理,BufferedStream对流的数据进行下缓存。原创 2023-08-22 16:48:15 · 1445 阅读 · 0 评论 -
C# 流Stream详解(1)——读写txt和二进制文件
我们知道在磁盘上只会存储二进制数据,文本文件最后也会被保存为二进制文件,我们调用接口读取和写入时虽然用的是string,但到底层一定是byte[]。这就涉及到string到byte[]的编码和byte[]到string的解码,只不过对于文本文件而言,有确定的编码解码规则,我们不需要关心。如果文件非常大,还是要用上面的方法读文件,否则一次性读进来,内存会爆。电脑手机上有各种各样的文件,例如视频文件、图片文件、文本文件,其中读写txt文件是最简单的,有多种方式,,在读取和写入文本时都可以传递文本编码参数。原创 2023-08-18 09:04:05 · 5804 阅读 · 0 评论 -
C#与C/C++交互(1)——需要了解的基础知识
C#中用于实现调用C/C++的方案是P/Invoke(Platform Invoke),让托管代码可以调用库中的函数。类似的功能,JAVA中叫JNI,Python中叫Ctypes。调用过程为查找dll,例子中为Test.dll'将该dll加载到内存中查找函数在内存中的地址,例子为查找Load函数,并将其参数按照函数的调用约定压栈,例子中调用约定为Cdecl将控制权转移给非托管函数。原创 2023-08-06 15:55:41 · 1660 阅读 · 0 评论 -
消息队列的实现
游戏的主逻辑一般是单线程的,所以实现一个消息队列很简单,不像互联网开发中会涉及多线程、多进程。可以先看看这篇文章。对回调函数和消息机制的理解_消息回调函数_永恒星的博客-CSDN博客这里尝试先去分析一些要素,然后直接基于这些要素去写代码,而不是边写边分析。对于实现一个消息队列,首先实现其基本功能,其次考虑各种不同的使用情况,在基本功能的基础上做额外的修改,最好考虑性能和内存,再做优化。原创 2023-05-07 21:13:39 · 1312 阅读 · 0 评论 -
字符串内存优化
字符串占用的内存往往很多,优化的空间很大,在做内存优化的时候,优化字符串内存是必不可少的一步。字符串内存优化的核心原则有三个:1.复用字符串,减少字符串数量2.降低不可复用字符串的占用的内存3.降低运行时产生的GC字符串内存在这个三个核心原则下又有一些具体的方法。原创 2023-03-11 11:04:22 · 872 阅读 · 0 评论 -
对回调函数和消息机制的理解
例如,在A类的a1方法中,会调用B类的b1方法,A类持有B类引用,可以采用方法调用在a1中完成对b1的调用。我们在a1中调用b1方法,b1里会去调其他方法,得到返回值,然后根据返回值调a2方法,在b1中我们只是知道了在满足某个条件时去调用a2,但不知道这个条件在a1调b1的过程中是否满足。如果是静态类,或者单例类,或者静态方法,就很方便,否则我们需要通过各种各样的方式将这个类的引用传递过来。可以认为回调函数在方法调用上包装了一层,是变相的方法调用,而消息是在回调函数的基础上包装了一层,是变相的回调函数。原创 2022-09-02 13:16:27 · 736 阅读 · 0 评论 -
理解C#枚举器和迭代器
【概念区分】穷举是找出所有符合某一个条件的对象的集合,例如全部对象有100个,分别是从1到100,条件是找出小于50的对象,穷举就是分别拿这100个对象与50对比来判断这个对象是否符合条件,将符合条件的对象放在一起构成一个集合。(这里为方便理解,举了一个很简单的例子,而实际上的穷举的全部对象可能是数万个,甚至无穷的)枚举是对一个已经存在的集合进行举例,找出集合中的每一个对象。要注意的是,也许我们刚开始不知道集合中有多少个对象,但当我们开始枚举之前是知道的。迭代是按照顺序的方式,一般是从前到后原创 2021-09-23 15:51:31 · 404 阅读 · 0 评论 -
C#垃圾回收触发条件
某一代预算容量被填满 显示调用GC.Collection Windows报告低内存 CLR正在卸载AppDomain CLR正在关闭【参考】《CLR via C#》原创 2020-09-11 09:28:21 · 385 阅读 · 0 评论 -
C#防止事件重复注册
【方法】在注册前先检查该订阅者是否已经注册过 在注册前先移除然后再注册【代码实现】using System;using System.Collections.Generic;using System.Reflection;namespace 笔试{ class Program { static void Main(string[] args) { MyDelegate myDelegate=new MyDel原创 2020-09-02 23:12:53 · 3984 阅读 · 1 评论 -
对继承中子类父类的转换及方法调用顺序的理解
阿达奥法和好原创 2020-08-21 17:06:34 · 294 阅读 · 0 评论 -
C# 数组Array.Sort()、List.Sort()排序使用方法
【对一维数组】数据:int[] A = {16, 67, 12, 50, 8, 46, 4}; 整体升序:Array.Sort(A); 整体降序:先升序,再反转Array.Reverse(A); 局部升序:Array.Sort(A,2,4);//从索引为2的元素开始的4个元素进行升序 局部降序:Array.Reverse(A,2,3);//对索引为2的元素开始的3个元素进行反转,这是接着Array.Sort执行的从左到右的图片分别是从整体升序到 的结果【对二维数组】数据:...原创 2020-08-27 11:07:09 · 23784 阅读 · 2 评论 -
C#List<T>源码详解
大多数原创 2020-08-16 13:10:38 · 2050 阅读 · 0 评论 -
C#对抽象类和接口的理解
【理解】抽象类和接口都包含着抽象的意味,但是两者所抽象的对象不同。接口是对关系微弱甚至毫无关系的多个对象的某一功能的抽象,抽象类是对有一定关系的多个对象的抽象。例如,汽车、人、猫、鸟都有移动的功能,但它们毫无关系,在接口中我们可以抽象出Move方法,让这四个对象都去实现,进而实现多态。牛、羊、马有一定关系,它们都会吃草,在抽象类中我们可以抽象出Eat方法,让这三个对象都去实现,也能实现多态。当然,完全可以用基类来定义Eat虚方法。用基类是把牛羊马看做一个具体的对象,在一个大型游戏中对象很多的,牛原创 2020-08-01 18:13:47 · 227 阅读 · 0 评论 -
结构体Cannot modify the expression because it is not a variable
看代码中结构体和类输出的B C值 class Program { static void Main(string[] args) { List<Te> myList = new List<Te>();//泛型list存放结构体 Te myTe = new Te(); ...原创 2020-04-23 20:51:54 · 238 阅读 · 0 评论 -
对C#继承的理解
继承是一种代码复用的方式,使得我们不必写重复的代码。例如,有三种怪物A、B、C,他们都有速度、血量、攻击力、防御值、攻击方式。如果没有继承我们可能要写三个脚本MonsterA、MonsterB、MonsterC,而且在某个脚本中我们还要重复的声明定义变量speed等。如果这有三种怪物,那么粘贴复制起来很快;如果有三十种怪物呢?那么粘贴复制起来就很烦。继承可以为我们解决这个问题。这时我们要多...原创 2020-04-28 18:39:52 · 189 阅读 · 0 评论 -
C#中类和结构体的区别
【区别】类是引用类型,结构体是值类型 类中的字段在声明时可以赋值,结构体中在声明字段时不能赋值 类中的构造器可以初始化部分字段,结构体中的构造器在必须初始化所有字段 类支持终结器,结构体不支持(结构体是值类型 ,以值的形式复制,难以知道在什么时候能安全执行终结器并释放结构体占用的非托管资源,垃圾回收器可以知道什么时候一个引用类型实例的引用不再活动,可在此之后的任何时间为这个引用类型运行终...原创 2020-01-16 18:33:15 · 389 阅读 · 0 评论 -
值类型和引用类型的嵌套
public class Test { public int a;//a是值类型,属于Test类的成员变量,位于Test实例化的对象所在的堆中 public int[] A;//A是引用类型,其值位于堆中,其引用也位于堆中 public void Method() { int b = 1;//...原创 2020-01-11 15:04:39 · 246 阅读 · 0 评论 -
C#StringBuilder和String的区别和使用
官方中文文档解释得很详细,超过绝大多数博客:https://docs.microsoft.com/zh-cn/dotnet/api/system.text.stringbuilder?view=netframework-4.8转载 2020-01-10 11:45:45 · 131 阅读 · 1 评论 -
对C#方法参数的理解
【前置知识】对值类型和引用类型的理解对C#中用new关键字实例化对象的理解【值参数】在调用方法时,将变量存储的数据复制给方法。具体而言,方法的参数(即形参)在内存中有自己的存储数据的空间,复制的数据被存储在其空间中。【例子】 class Program { static void Main(string[] args) { ...原创 2020-01-03 18:24:21 · 498 阅读 · 0 评论 -
对C#构造器的理解
【前置知识】对C#中用new关键字实例化对象的理解【构造器的作用】在实例化对象时需要给一些必要的初始数据(即对象初始化),构造器决定了哪些数据是必要的,而我们可以通过构造器来给这些数据赋值,而不使用其默认的值。注解:对象需要哪些数据本质上是我们决定的,因为类是我们写出来的,而在C#中要对象创建出来时,对象需要的数据要通过构造器来知道,所以可以说构造器决定了对象需要哪些数据。这是...原创 2019-12-30 15:02:11 · 2747 阅读 · 0 评论 -
对C#数组声明方式的理解
【最重要的两个条件】在声明数组时有两个非常重要的条件,只有满足这两个条件,声明出来的数组才能保证在程序运行的时候不出错,这两个条件是:声明的数组要有初始值 声明的数组要有存储的位置(即有分配内存给数组存储数据)【数组的声明方式】【方式一】 int[] array;//声明数组 array=new int[3];//数组实例化声明的数组要有初始值:虽然我们没有赋初始值,但...原创 2019-12-24 16:57:21 · 288 阅读 · 0 评论 -
对C#中用new关键字实例化对象的理解
【前置知识】对值类型和引用类型的理解公共语言运行时CLR对C#数组声明方式的理解【实例化格式】类名 对象名 = new 类名 (参数列表)【相关概念辨析】类是模板,定义了对象在实例化的时候看起来像什么样子。对象是类的一个实际的例子,简称实例。实例化是从类创建对象的过程。举例而言:类可以看做是图纸,我们根据这个图纸做出来一个东西(即对象),做出来的东西就是图...原创 2019-12-27 16:27:50 · 8016 阅读 · 2 评论 -
对C#装箱和拆箱的理解
【什么是装箱和拆箱】装箱(box)是将值类型转换为引用类型的过程,拆箱(unbox)是将引用类型转换为值类型的过程【装箱过程】先在堆上分配存储位置。(注解:引用类型的数据值放在堆中) 将值类型数据的值复制到分配好的储存位置 返回储存位置的地址(即引用)(注解:装箱过程有分配内存和复制数据两个耗费性能(即影响程序整体性能)的操作)【拆箱过程】先检查当前的引用类型数据是否可以...原创 2019-12-21 14:43:39 · 294 阅读 · 0 评论 -
对数据类型的理解
【对数据的分类】自然界中存在各种各样的数据,我们将这些数据根据其特点分为不同的类型。在这一阶段分类跟我们用什么语言(C#、C++、Java等)没有任何关系。这些数据不是我们规定出来的,而是本来就存在在自然界中的。可以将这些数据分为两类,其中一类是数,另一类是符。【数】在计算机中,将数分为整数类型(简称整型)、浮点类型(简称浮点型)。根据计算机存储数据的特点,整型又可进一步分为i...原创 2019-12-19 16:33:37 · 761 阅读 · 0 评论 -
对值类型和引用类型的理解
【前置知识】内存中有栈区(stack)和堆区(heap)来存放数据。对值类型和引用类型的区别这个问题而言,我们只需要明白以下两点即可:在空间大小上,栈<推 在读取速度大小上,栈>推【拓展】内存中的堆和栈到底是什么【定义】按照数据在内存中的存储位置,可以将所有数据分为值类型和引用类型两类。有类数据的规模(即数据量)很小,所以需要的空间也小,其通常存储在栈区,也即栈...原创 2019-12-21 16:57:10 · 512 阅读 · 0 评论 -
C#托管代码和非托管代码的区别
【前置知识】写好的程序在运行的时候会经过以下过程(即C#编译过程):源代码(即用C#语言写好的代码)被C#编译器转换为公共中间语言(Common Intermediate Language,CIL)代码 CIL代码被公共语言运行库(Common Language Runtime,CLR)转换为机器码 (注解:【A】说法上,公共...原创 2019-12-10 17:20:08 · 2670 阅读 · 0 评论