【发布时间】:2019-02-02 22:26:09
【问题描述】:
对于我正在编写的一些通用辅助方法,我希望能够在该值是其类型的默认值时调用特殊处理。对于引用类型,这很简单——默认值为null。我不能使用泛型类型参数,尽管我可以解决这个问题。
我可以这样做:
public bool DetectPossiblyUninitializedValue(object val) {
return val== null ||
val.GetType().IsValueType
&& Equals(val, Activator.CreateInstance(val.GetType());
}
这就是我现在正在使用的,但这取决于Equals 的实现。这很好,但并不理想。特别是,某些实现可能会覆盖 Equals 以在正常情况下支持更多可用的语义。在这里将默认值视为特殊值实际上并不少见,因为在 .NET 中由于默认初始化,它是如此不可避免。
但是,在这种情况下,我只想知道对象是否已初始化,因此我不想要任何自定义相等或其他任何东西。基本上,我想知道 struct 占用的内存区域是否在初始化后填充为零作为 VM 保证,仅此而已。从某种意义上说,我正在为结构寻找类似于 ReferenceEquals 的东西:一种忽略底层对象自身实现的比较。
如何在不使用Equals 的情况下比较原始结构值?我可以比较原始结构值吗?
编辑:我正在使用它来连接代表特定领域概念的类+结构,这些概念由代表各种业务规则的基本上任意代码连接到 GUI。一些旧代码本质上处理可能嵌套的字符串字典到任意对象,因此需要一堆未经检查的强制转换或dynamic;创建这些很容易出错。因此,能够相对直接地使用类型化对象是件好事。另一方面,对 GUI 和包装代码以不同方式处理可能未初始化的值很有用;尽管可以采用逐个案例、逐个类型的解决方案,但这是很多代码;合理的默认设置很有用。我真正想要的是一种自动生成与另一个类型相同但所有属性/公共字段扩展为包含“未初始化”值的类型的方法,但这不是期望的现实特征 - 相比之下,在动态世界中,这将是微不足道的实现,虽然在其他地方没有类型安全......
答案: Mehrdad 在how to directly access the bits of structs 上发布了答案;我加了an implementation using that to detect possibly uninitialized values。
【问题讨论】:
-
可以使用反射吗?您可以比较结构中成员的值/引用。
-
我绝对可以使用反射——但这只是延迟了问题。我该怎么办会员?递归......直到什么?
-
请注意,有一些细微的例外,例如双精度数,其中 -0.0 == 0.0,即使位模式不同。
-
结构的ReferenceEquals?只返回 false 的方法呢?
-
没错——
aka ReferenceEquals for structs没有意义...
标签: c# reflection