C# 不可空字段:Lateinit?

2023-11-26

我想知道如何使用后期初始化C# 中的类字段可为空的引用类型。 想象一下下面的类:

public class PdfCreator { 

   private PdfDoc doc;

   public void Create(FileInfo outputFile) {
       doc = new PdfWriter(outputFile);
       Start();
   }

   public void Create(MemoryStream stream) {
       doc = new PdfWriter(stream);
       Start();
   }

   private void Start() {
      Method1();
      // ...
      MethodN();
   }

   private void Method1() {
      // Work with doc
   }

   // ...

   private void MethodN() {
      // Work with doc
   }
}

上面的代码非常简化。我的真实班级使用更多字段,例如doc并且还有一些带有一些参数的构造函数。

使用上面的代码,我在构造函数上收到编译器警告,即doc未初始化,这是正确的。我可以通过设置类型来解决这个问题doc to PdfDoc?,但是我必须使用?. or !.到处都在使用它,这很令人讨厌。

我也可以通过doc作为每个方法的参数,但请记住,我有一些这样的字段,这违反了我眼中的干净代码原则。

我正在寻找一种方法来告诉编译器我将初始化doc在使用它之前(实际上我这样做了,调用者不可能得到空引用异常!)。我认为 Kotlin 有lateinit修饰符正是为了这个目的。

您将如何用“干净”的 C# 代码解决这个问题?


到目前为止我发现的最好的解决方案是这个:

private PdfDoc doc = null!;

这通过使用删除所有编译器警告空值宽容运算符C# 8 中引入。它允许您使用一个值,就好像它不为空一样。因此,它的一种使用方式是当您需要类似于 Kotlin 的“lateinit”。与Kotlin的lateinit不同,这里它实际上会被初始化为null,这是编译器和运行时都允许的。如果你以后在不需要null的地方使用这个变量,你会得到一个NullReferenceException,并且编译器不会警告你认为它可能为空,因为它会认为它不为空。Kotlin 的 Lateinit 有一个微妙的区别,如果你在初始化之前访问了一个 Lateinit 属性,它会抛出一个特殊的异常,清楚地标识正在访问的属性以及以下事实:它尚未初始化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 不可空字段:Lateinit? 的相关文章

随机推荐

  • 使用 BeautifulSoup CSS 选择器获取文本

    HTML 示例 h2 ABC span class numbers 123 span span class lower abc span h2 我可以通过以下方式获取数字 soup select name gt span numbers 0
  • 同一类型的多个对象集

    我尝试在 EF5 RC 中创建与此类似的数据上下文 class WordContext DbContext public DbSet
  • Javascript 类型数组和字节顺序

    我正在使用 WebGL 渲染二进制编码的网格文件 二进制文件以大端格式写入 我可以通过在十六进制编辑器中打开文件或使用 fiddler 查看网络流量来验证这一点 当我尝试使用 Float32Array 或 Int32Array 读取二进制响
  • NSNotificationCenter 选择器未被调用

    在我的 iPad 应用程序中 我在一堂课中注册了一条通知 NSNotificationCenter nc NSNotificationCenter defaultCenter nc addObserver self selector sel
  • 如何更改Android顶部工具栏菜单项图标大小

    如何更改 Android 工具栏中菜单项的大小 目前菜单的尺寸非常小 我想增加尺寸 如果有人知道请帮助我找到解决方案 应用程序栏 xml
  • 验证访问令牌 - Asp.Net 身份

    我正在使用 ASP Net Identity 来实现外部登录 用户使用 Google 登录后 我获得了 google 的外部访问令牌 然后我进行第二次 api 调用获取LocalAccessToken 它将外部访问令牌换成新的本地访问令牌
  • Android 如何获取两个时区之间的时差?

    我需要获取不同时区的两个日期之间的时差 目前我正在这样做 Calendar c1 Calendar getInstance TimeZone getTimeZone EDT Calendar c2 Calendar getInstance
  • 适用于 Windows 和 Linux 的 Go 中的命名管道

    我是 Go 新手 我想在 Go 中创建命名管道实现 它可以在 Windows 和 Linux 上运行 我设法让代码在 Ubuntu 上运行 但是这个代码在 Windows 上不起作用 Go 中是否没有任何抽象允许您在两种环境中使用命名管道
  • 如何使用 React Native 强制用户更新应用程序

    我已经在应用程序和 Play 商店中更新了我的应用程序 并且我想强制我的应用程序用户在应用程序商店和 Play 商店中更新应用程序的新版本 您可以使用此库检查应用程序的 App Store Play Store 版本反应本机应用商店版本检查
  • JSON对象到文档

    您好 我是 mongodb 新手 我想将 JSONObject 转换为文档 然后将其存储到 mongodb 这是我编码的内容 我得到了一个 json 格式的服务 api CloseableHttpResponse response http
  • 禁用来自NotificationChannel的声音

    今天我开始瞄准 API 26 这迫使我使用通知通道 我的问题是 现在每个新通知 包括更新 都会播放烦人的声音 如何禁用此声音 我尝试用自定义 mp3 声音替换此声音 然后将其传递为静音的 mp3 但这被忽略 我只是添加一个优先级非常低的通知
  • 如何在加载实际内容之前加载小占位符图像

    我有一个关于图像加载样式的问题 如图所示http www e flux com 该网站首先 随机 加载特定图案的图像 然后再继续显示实际图像 我的猜测是 这是在加载整个网站之前就拥有视觉上令人愉悦的内容 我查看了源代码 发现它有一类 laz
  • 如何从 xml 文件中删除 BOM 字符 [重复]

    这个问题在这里已经有答案了 我正在使用 xsl 来控制 xml 文件的输出 但正在添加 BOM 字符 vim file xml set nobomb wq
  • Java 日历的设置值没有给出预期的日期时间

    我有一个小时 分钟 日期和毫秒时间戳 并且正在尝试创建一个表示时间的 Date 对象 时间戳以东部夏令时间提供 在剖析这个问题时 我创建了一些简单的测试代码来查看发生了什么 并观察到以下情况 Date today new Date int
  • 如何将 QMetaMethod 与 QObject::connect 一起使用

    我有两个 QObject 子类实例和一个对象中信号的两个 QMetaMethod 实例以及另一个对象中插槽的两个实例 我想将这个信号和插槽相互连接 我查看了 qobject h 文件 发现 SIGNAL 和 SLOT 宏只是在方法签名的开头
  • 如何在 slick + postgresql 上进行分页选择

    在使用 slick 3 的 postgresql 数据库中 分页的最佳方式是什么 获取所有行并使用 scala 进行分页 似乎效率不高 带限制和偏移量的静态查询 还有其他办法吗 您可以使用take and drop上的方法TableQuer
  • 如何向连续几天的“连续”行中添加运行计数

    谢谢Mike添加创建 插入语句的建议 create table test pid integer not null date date not null primary key pid date insert into test value
  • 时间单元测试的想法和技巧?

    有人做过时间单元测试吗 我什至不确定这样的术语是否已被创造 但重点是测试操作是否在时间限制内执行 我有一些算法 我想测试它们的执行时间是否按预期增加 我想类似的测试可以用于 IO 以及什么不是 有点像 test timeout 之类的 然而
  • 在 WF4 中工作流定义更改后加载持久工作流

    如何解决这个问题 在WF4中 我在 xaml 中创建一个工作流程并启动它的多个实例 我有一个持久性存储 并且所有工作流程都保留在其工作流程一半的书签上 现在我停止应用程序 如果我重新启动应用程序 一切都会恢复 并且很好地完成 但是 如果我想
  • C# 不可空字段:Lateinit?

    我想知道如何使用后期初始化C 中的类字段可为空的引用类型 想象一下下面的类 public class PdfCreator private PdfDoc doc public void Create FileInfo outputFile