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

C#笔记啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

各数据类型的字节数

byte、sbyte、bool、char1
short、ushort2
int、uint、float4
long、ulong、double8
string(栈内存的引用地址)32位4,64位8

反射总结

得到Type

typeof(类名);
实例.GetType();
Type.GetType("命名空间.类名");

得到公共成员

MemberInfo memberInfos[]=type.GetMembers();

得到构造函数

得到所有:

ConstructorInfo[] constructorInfos=type.GetConstructors();

得到无参:

ConstructorInfo constructorInfo=type.GetConstructor(new Type[0]);
MyClass myClass=constructorInfo.Invoke(null) as MyClass;

得到有参:

ConstructorInfo constructorInfo2=type.GetConstructor(new Type[]{typeof(参数类型)});
myClass=constructorInfo2.Invoke(new object[]{2}) as MyClass;

Activator快速实例化

myClass=Activator.CreateInstance(type) as MyClass;

得到公共字段

按字段名得到:

FieldInfo fieldInfo=type.GetField(string 字段名);

得到所有字段

FieldInfo[] fieldInfos=type.GetFields();

公共字段读写

fieldInfo.GetValue(实例);
fieldInfo.SetValue(实例,数据);

得到公共方法

得到所有

MethodInfo[] methodInfos=type.GetMethods();

按方法名得到:

MethodInfo methodInfo=type.GetMethod(string 方法名,new Type[]{typeof(参数1类型),...});

执行公共方法

实例方法

methodInfo.Invoke(实例,new object[]{参数1,...});

静态方法

methodInfo.Invoke(null,new object[]{参数1,...});

获得List的Fields,什么都没得到

List<int>data=new List<int>(){123,14,4234};
Type dataType=data.GetType();
FieldInfo[] fieldInfos=dataType.GetFields();

正确用法:把List装到一个class里。

deepseek回答字典的底层机制

C# 的 Dictionary<TKey, TValue> 使用 ‌链地址法(Chaining)‌ 的改良实现来解决哈希冲突,这是一种基于数组索引的虚拟链表结构而非物理离散节点24。其核心设计融合了数组的连续存储优势和链表的冲突处理能力,具体实现如下:


一、底层数据结构与冲突解决机制

  1. 双数组结构

    • buckets[] 数组‌:存储桶的头节点索引(指向 entries[] 的位置),初始值为 -1 表示空桶45。
    • entries[] 数组‌:连续存储键值对(Entry 结构体),每个 Entry 包含:
      struct Entry {public int hashCode; // 哈希码(低31位)public int next;     // 冲突链的下一个节点索引(-1 表示结尾)public TKey key;public TValue value;
      }
      
      通过 next 字段形成逻辑链表,解决哈希冲突45。
  2. 冲突处理流程
    当插入键值对时:

    • 计算键的哈希值 hashCode,映射到 buckets 数组的索引 bucketIndex45。

    • 若 buckets[bucketIndex] 为 -1,直接存入 entries[] 的新位置。

    • 若发生冲突(buckets[bucketIndex] 非 -1),将新 Entry 的 next 指向当前桶的头节点,并更新 buckets[bucketIndex] 为新节点的索引67。
      本质是通过 next 字段在连续数组内模拟链表操作‌,而非动态分配离散节点46。


二、为何未采用开放地址法(Open Addressing)

  1. 内存与性能权衡

    • 开放地址法要求所有数据存储在单一连续数组,扩容时需全量迁移,代价高昂810。
    • 链地址法通过逻辑链表分离冲突数据,扩容仅需重建 buckets 索引,entries 数组可部分复用610。
  2. 删除操作高效性

    • 开放地址法删除需标记“墓碑”位置,导致查找路径变长10。
    • 链地址法直接修改 next 指针即可删除节点,无需特殊标记910。
  3. 高装载因子容忍度

    • 当装载因子 >1 时(如数据量远超桶数量),链地址法仅延长链表长度,而开放地址法性能会急剧退化810。
    • C# Dictionary 默认装载因子为 0.72,超过时触发扩容56。

三、改良链地址法的优势

  1. 缓存友好性
    entries[] 数组连续存储,相比物理链表减少内存碎片,提升 CPU 缓存命中率47。
  2. 预分配与复用
    初始化时预分配 entries[],删除节点时通过 freeList 链表复用空位,减少内存分配开销67。

总结对比

特性C# 字典的链地址法改良传统开放地址法
冲突解决数组内虚拟链表 (next 索引链) 47线性/二次探测空槽 310
内存连续性键值对在 entries[] 中连续存储 4所有数据在单一数组连续存储 10
删除效率直接修改索引链,高效 69需标记墓碑,影响查找 10
高负载因子适应性链表长度增加,性能线性下降 10性能急剧退化 810

因此,C# Dictionary 通过‌数组化链地址法‌,在内存效率、冲突处理与动态扩容间取得了平衡4

追问:这么看来buckets数组是一个整数数组?

是的,C# 的 Dictionary<TKey, TValue> 中的 buckets 数组是一个‌整数数组(int[]‌,其核心作用是通过存储索引值来关联哈希桶与键值对数据。具体实现细节如下:


一、buckets 数组的结构与功能

  1. 数据类型与用途

    • buckets 数组的每个元素是 int 类型,存储的是 entries 数组的索引值(即键值对在 entries 中的位置)15。
    • 初始化时,buckets 的所有元素默认值为 -1,表示空桶5。
  2. 哈希映射流程

    • 当插入或查找键值对时,哈希函数计算键的哈希值,并通过取模运算映射到 buckets 的某个索引 bucketIndex46。
    • 若 buckets[bucketIndex] 为 -1,表示无冲突,直接存入 entries;否则通过 next 字段形成逻辑链表解决冲突15。

二、buckets 与 entries 的协同关系

  1. entries 数组的存储

    • entries 是 Entry 结构体数组,包含 hashCodenextkey 和 value 字段5。
    • next 字段指向同一哈希桶中的下一个 Entry 索引(类似链表指针),形成冲突链16。
  2. 内存布局示例

    textCopy Code

    buckets = [ -1, 2, -1, 0 ] // 桶索引 3 指向 entries[0] entries = [ { hashCode=123, next=1, key="K1", value="V1" }, // 冲突链头 { hashCode=123, next=-1, key="K2", value="V2" } // 冲突链尾 ]


三、设计优势与性能考量

  1. 高效的内存利用
    • 整数数组 buckets 占用空间小,且通过 entries 的连续存储减少内存碎片45。
  2. 快速冲突解决
    • 逻辑链表(通过 next 索引)比物理链表(如 LinkedList)更缓存友好,减少指针跳转开销14。

总结

  • buckets 是 int[] 类型,核心功能是通过索引关联哈希桶与 entries 中的键值对15。
  • 这种设计结合了数组的连续性和链表的冲突处理能力,兼顾了哈希表的高效查找与动态扩展需求

人话总结

字典有2个数组:整数数组buckets,结构体数组entries,哈希冲突的键会得到同一个bucketsIndex,buckets的值是这些哈希冲突的键值对中的第一个在entries的索引,通过entry结构体的next找到下一个键值对索引,直到找到next==-1的也就是最后一个键值对,把新键值对加入entries最后,next==-1的键值对next改成新加入的键值对索引。

如果某个bucketsIndex下的值是-1,则直接加入entries最后,buckets[bucketsIndex]改成这个新加的索引。

键值对在内存是连续、乱序的。

http://www.dtcms.com/a/331777.html

相关文章:

  • 机器学习学习报告
  • 【博客系统测试报告】---接口自动化测试
  • AI幻觉终结之后:GPT-5开启的“可靠性”新赛道与开发者生存指南
  • JAVA中正则表达式详解
  • 前端八股文-CSS3篇
  • 考研408《计算机组成原理》复习笔记,第四章(2)——指令寻址和数据寻址
  • K8s-kubernetes(二)资源限制-详细介绍
  • 2025 年电赛 C 题 发挥部分 1:多正方形 / 重叠正方形高精度识别与最小边长测量
  • 悲观锁乐观锁与事务注解在项目实战中的应用场景及详细解析
  • 如何解决EMI中传导干扰
  • Spring-解决项目依赖异常问题
  • 【从零开始java学习|第六篇】运算符的使用与注意事项
  • 因果推断在用户流失预警的案例研究
  • 第2节:多模态的核心问题(多模态大模型基础教程)
  • 【Unity3D】Spine 3.8版本使用记录
  • 机器学习入门:从概念到实践的核心知识梳理
  • 【Linux系统】进程的生命旅程:从创建到独立的演绎
  • 智能体评测技术与实践:从评估维度到DeepEval实战指南
  • LeetCode Day6 -- 图
  • 速卖通商品详情接口深度开发:从多语言解析到跨境合规处理
  • 从零开始搭建React+TypeScript+webpack开发环境——基于MobX的枚举数据缓存方案设计与实践
  • react + i18n:国际化
  • HTML5二十四节气网站源码
  • 【web自动化】-1- 前端基础及selenium原理和环境安装
  • 传输层协议TCP(3)
  • Observer:优雅管理事件订阅的秘密武器
  • TCP 连接管理:深入分析四次握手与三次挥手
  • C++:浅尝gdb
  • 创客匠人:共情力在创始人IP塑造中的作用
  • 使用Docker和Miniconda3搭建YOLOv13开发环境