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

TEngine学习

关于静态类中的静态变量赋值:

   public static class ActorEventDefine{public static readonly int ScoreChange = RuntimeId.ToRuntimeId("ActorEventDefine.ScoreChange");public static readonly int GameOver = RuntimeId.ToRuntimeId("ActorEventDefine.GameOver");public static readonly int EnemyDead = RuntimeId.ToRuntimeId("ActorEventDefine.EnemyDead");public static readonly int PlayerDead = RuntimeId.ToRuntimeId("ActorEventDefine.PlayerDead");public static readonly int AsteroidExplosion = RuntimeId.ToRuntimeId("ActorEventDefine.AsteroidExplosion");public static readonly int EnemyFireBullet = RuntimeId.ToRuntimeId("ActorEventDefine.EnemyFireBullet");public static readonly int PlayerFireBullet = RuntimeId.ToRuntimeId("ActorEventDefine.PlayerFireBullet");}

在 Unity 中,static readonly 字段的赋值时机遵循 .NET 的规则:

当第一次访问 ActorEventDefine 类本身或其中的任何成员时,CLR 会执行该类的类型初始化(Type Initializer)

此时,所有 static readonly 字段会按顺序执行赋值(即调用 RuntimeId.ToRuntimeId(...))。

关键点:

  • 延迟初始化:直到首次访问时才会执行,而非游戏启动时立即执行。

  • 线程安全:CLR 保证静态构造函数是线程安全的,多线程访问时不会重复初始化。

  • 性能:由于 RuntimeId.ToRuntimeId 可能是计算密集型操作,首次访问可能会有轻微延迟,但后续访问无额外开销。


具体流程:

  1. 首次访问触发
    当你第一次通过代码访问 ActorEventDefine.ScoreChange 或其他字段,或显式使用 ActorEventDefine 类时(例如在初始化时注册事件监听),CLR 会检查该类是否已初始化。

  2. 静态构造函数执行
    由于代码中没有显式定义 static ActorEventDefine() 构造函数,编译器会自动生成一个隐式的静态构造函数,其中包含所有 static readonly 字段的赋值逻辑。

  3. 字段初始化顺序
    所有 static readonly 字段会按代码中的顺序初始化(ScoreChangeGameOver → ...),且仅执行一次,后续访问直接复用已初始化的值

出处:

根据 Microsoft C# 编程指南官方文档 的说明:

“如果未提供静态构造函数来初始化静态字段,会将所有静态字段初始化为其默认值。如果静态构造函数类中存在静态字段变量初始值设定项,它们将以在类声明中显示的文本顺序运行。初始值设定项紧接着静态构造函数之前运行。”

这意味着,当你没有显式定义一个 static ActorEventDefine() 构造函数时,编译器会自动生成一个隐式的静态构造函数(即“类型构造器”),并将所有 static readonly 字段的初始化代码插入到这个构造器中,按声明顺序执行。

此外,CLR via C# 一书中也明确指出:

“当你使用内联语法初始化静态字段时,C# 编译器会将这些初始化语句移动到它自动生成的类型构造器中。”

因此,“编译器会自动生成一个隐式的静态构造函数”这一行为在官方文档和技术规范中均有明确依据,并非推测。

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

相关文章:

  • 【Noah-MP模型】陆面生态水文模拟与多源遥感数据同化的实践技术应用
  • JavaScript进阶篇——第六章 内置构造函数与内置方法
  • alpineLinux修改包管理为国内源
  • 越野小车结构设计\越野小车设计cad【6张】三维图+设计说明书
  • 【Java】【力扣】101.对称二叉树
  • 数据结构与算法——Leetcode215. 数组中的第K个最大元素
  • 中国1km分辨率逐月平均气温数据集 - matlab按shp批量裁剪
  • Git远程仓库与协作技巧详解
  • 【add vs commit】Git 中的 add 和 commit 之间的区别
  • 秘塔AI搜索的深度研究推出:它的“免费午餐”还能走多远?
  • NULL值处理:索引优化与业务设计实践指南
  • GIT版本回退
  • 堆排序算法详解:原理、实现与C语言代码
  • ubuntu--自启动程序
  • Docker Compose 清理指南:`down` 与 `down -v` 的核心区别与使用场景
  • Jenkins credentials 增加了github credential 但是在Git SCM 凭证中不显示
  • 基于SpringBoot+Uniapp球场预约小程序(腾讯地图API、Echarts图形化分析、二维码识别)
  • 如何用 Charles 中文版抓包工具高效调试 API 并优化网络性能
  • 自适应哈希索引 和 日志缓冲区
  • 结构体(二)
  • XXE漏洞1-XXE 漏洞简介-XML 语法-DTD 讲解-外部实体讲解
  • 【React Native】安装配置 Expo Router
  • HTML基础P1 | HTML基本元素
  • Jmeter中Parallel Controller的配置方法(并发)
  • 小白学HTML,操作HTML文件篇(2)
  • 二进制枚举
  • 基于Canal实现MySQL数据库数据同步
  • 百炼Agent MCP与IoT实战(二):阿里云MQTT Broker配置
  • Unity UGUI 无限循环列表组件
  • 倒立摆系统控制器设计报告