C# - “对象引用未设置到对象的实例”

2023-12-22

我目前正在尝试在“MyMethod”使用引用之前检查引用是否为空:

if (School.ClassRoom.Pupil.Age != null)
        {
            MyMethod(School.ClassRoom.Pupil.Age);
        }

但是,我仍然在第一行收到“对象引用未设置为对象实例”的信息,因为不仅年龄为空,而且学生和教室有时也为空。

我在使用 Try、Catch、Finally 时遇到了同样的问题,因为我在 Try 代码段中遇到了相同的错误。

我不想每次使用此方法时都必须检查每个 ClassRoom 是否为 null,然后检查每个 Pupil 是否为 null,然后检查每个 Age 是否为 null。

有没有更简单的方法来做到这一点?


注:下面的答案写于 2010 年,早在空条件C# 6 中引入了运算符。


听起来您正在寻找类似 Groovy 的空安全解引用运算符之类的东西,它可以让您编写if (School?.ClassRoom?.Pupil?.Age != null)- 但 C# 在 C# 6 之前没有这样的东西。

我怕你have检查每个属性是否无效,假设它可以be null:

if (School != null && School.ClassRoom != null && School.ClassRoom.Pupil != null
    && School.ClassRoom.Pupil.Age != null)
{
    MyMethod(School.ClassRoom.Pupil.Age);
}

当然,你可以把这整个if块将方法调用本身包含在辅助方法中,然后调用它。

假设每个属性都有效be开头为空。如果您能够设计您的类,甚至不允许空值 - 并且您在构造函数等中验证这一点 - 您的代码最终可能会变得更加干净。

值得注意的是,这里有两种替代方法 - Chris 在另一个答案中提出的方法是为每个属性创建一个“默认”对象;我usually发现最好始终要求在构造函数中提供“真实”值。没有真实数据的默认对象最终可能会导致错误,这些错误比错误更难追踪NullReferenceException问题,因为您可以愉快地长期使用“虚拟”数据,但最终得到错误的结果。肯定有这样的时候is然而,这是正确的做法——尤其是在收藏方面。这取决于实际情况。

编辑:萨伊德在评论中建议了一种扩展方法。我认为这会是这样的:

public static int? PupilAgeOrNull(this School school)
{
    return school != null && 
           school.ClassRoom != null && 
           school.ClassRoom.Pupil != null
           ? school.ClassRoom.Pupil.Age : null;
}

(适当调整类型。)

我绝对更喜欢尝试在其他地方保持非空值的想法,但是如果您需要它,这将做到这一点。但我感觉不对。这种直觉的核心是你一开始就在浏览三到四个属性——这感觉像是违反了德墨忒耳定律 http://en.wikipedia.org/wiki/Law_of_Demeter大部头书。现在我不是一个对这些事情教条的人,而是放置一个扩展方法on School对于这么长的属性路径,我感觉太具体了。

另一种选择 - 在我看来也有点令人讨厌 - 是编写三种不同的扩展方法:

public static ClassRoom ClassRoomOrNull(this School school)
{
    return school == null ? null : school.ClassRoom;
}

public static Pupil PupilOrNull(this ClassRoom classRoom)
{
    return classRoom == null ? null : classRoom.Pupil;
}

public static int? AgeOrNull(this Pupil pupil)
{
    return pupil == null ? null : pupil.Age;
}

然后你可以写:

int? age = School.ClassRoomOrNull().PupilOrNull().AgeOrNull();
if (age != null)
{
    MyMethod(age);
}

这意味着扩展方法School并不是那么具体。你仍然有一个很长的方法调用链,如果可能的话,我仍然会尝试重新设计以避免这种情况,但至少没有那么紧密的联系School to School.ClassRoom.Pupil.Age.

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

C# - “对象引用未设置到对象的实例” 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • 我如何为特定列中的每个值添加总计行,该行基于其他列进行计算,

    假设我有这个数据框 我想要的是这个 我想要做的是创建根据月份变量进行分组的行 然后获取总变量的总和 以及该月所有值的 days month 变量的唯一值 我只是想知道是否有一种简单的方法可以做到这一点 不涉及多次传播并收集装饰总计 我必须在
  • C# 2D 游戏编程教程

    我想学习用 C 编写 2D 游戏 有哪些面向初学者 针对 C 编写 最好使用 GDI 或同样简单的东西 的最佳教程 我依靠这个社区的经验来引导我走向最好的方向 Books 开始 NET 游戏编程 https rads stackoverfl
  • Python Svgwrite 和字体样式/大小

    我正在尝试制作一个连接到网络抓取工具的 SVG 文件 如何使用 svgwrite 更改字体和文本大小 我知道我必须定义 CSS 样式并以某种方式将其连接到文本对象 但这是如何制作的呢 这是我到目前为止的代码 import svgwrite
  • 存储部分和的二叉树:名称和现有实现

    Consider a sequence of n positive real numbers ai and its partial sum sequence si Given a number x 0 sn we have to find
  • 使用脱字符号 (^) 拆分长命令不适用于批处理文件中的管道 (|)

    答案关于这个问题 https stackoverflow com q 69068 3705191声明可以通过使用插入符将长命令分成多行 一个答案提供了技术描述 插入符号 and 换行符其后的被删除完全来自命令 然而 这似乎并不总是有效pip
  • 如何处理 C 中的 free() 错误?

    假设我已经使用了free 函数来释放内存 由于多种原因 我不允许这样做 如何阻止我的 C 应用程序崩溃并生成错误并继续执行 我这里没有 try catch 类型的规定 例如 C java 有什么办法可以忽略这个错误并继续执行吗 If yes
  • React Native 中的 OCR 库。可以使用 tesseract.js 吗?

    我应该使用什么免费库来在 React Native 中进行扫描 我需要一个库来扫描文档 我想在相机上设置帧大小并从照片加载数据 我找到了一个库 但它不会再维护了 https github com jonathanpalma react na
  • git:如何重新同步 fork?

    我们需要遵循的工作流程是这样的 将 github 上的项目分叉到您自己的私人 githib 帐户中 将分叉项目克隆到本地计算机 在本地计算机上创建 主控的 功能分支 将分支提交到分叉存储库 在主存储库上向分叉存储库上的新分支发出拉取请求 这
  • C# 与 Java HmacSHA1,然后是 base64 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个 java 代码示例 用于使
  • 脚本上的 BigQuery 请求超时错误

    在 BigQuery 上运行查询作业时出现错误 消息 gt 请求超时 请再试一次 原因 gt 超时 位置 gt 脚本 我们将按照要求再次运行它 但由于它需要 1 2 小时才会超时 因此如果我们知道问题是什么 这样我们就可以避免它 这将很有帮
  • 字段列表中的未知列。 PHP+MySQL

    我试图将值添加到 phpmyadmin 中的表中 但收到错误 字段列表 中的未知列 这是我的代码
  • 使用 intel pin 工具的堆栈分配大小

    我有以下 c 代码 include
  • AttributeError:“unicode”对象没有属性“_sa_instance_state”

    我刚刚学习如何使用 SQLAlchemy 我正在尝试执行以下操作 但将标题和链接存储在两个单独的表中 temp Submissions title u Facebook Homepage link u http facebook com s
  • 如何(重新)调用已初始化对象的构造函数?

    我正在编写一些代码来检查特定的 MIDI 设备是否已插入 如果没有 则代码每 5 秒重新检查一次 直到插入为止 我的问题出现在检查设备列表时 外部库没有重新检查端口的功能 因为它只在类的构造函数中执行此操作 我能看到让我的代码重新检查设备列
  • hibernate 选择所有投影分组依据

    在hibernate Criteria规范中 如果我想对表中的属性进行分组 我必须使用Projections groupProperty 问题是我无法选择表中的所有字段 我想要的是 SELECT FROM 实体 GROUP BY 字段 如果
  • C Python API 扩展忽略 open(errors="ignore") 并始终抛出编码异常

    给定一个文件 myfiles file with invalid encoding txt无效的 UTF8 为 parse this correctly F B r also parse this correctly 我正在使用内置的Pyt
  • 使用CMD终端时Python无法显示希伯来语

    我正在尝试在我的代码中使用希伯来字符 但我的终端 CMD 不支持希伯来语 而是只显示随机问号 例如 gt gt gt Print result 编辑 CMD 控制台的默认字体中根本没有希伯来字母 您只需更改字体即可显示希伯来语 这将影响命令
  • powershell出现错误时如何获取错误代码?

    我的片段是这样的 msg Remove Item Recurse Force C users bkp 2 gt 1 if LASTEXITCODE eq 1 Encountered error during Deleting the Fol
  • InternetReadFile 的常见平均缓冲区大小是多少?

    我在 Delphi 中使用 WinInet h 通过 HTTP 下载平均大小在 30 KB 到 1 5 MB 之间的文件 var Buf array 0 BUFFER SIZE 1 of Byte while BOOL InternetRe
  • C# - “对象引用未设置到对象的实例”

    我目前正在尝试在 MyMethod 使用引用之前检查引用是否为空 if School ClassRoom Pupil Age null MyMethod School ClassRoom Pupil Age 但是 我仍然在第一行收到 对象引