【问题标题】:Determine if Type is a pure "Data Type"确定 Type 是否为纯“数据类型”
【发布时间】:2018-08-16 20:35:45
【问题描述】:

Microsoft 在其文档中将我认为的“编程原语”(我理解这是用词不当)列为“数据类型”。因此,按度量标准列出的“数据类型”对象列表如下:

布尔值 字节 字符 日期 十进制 双倍的 整数 长 目的 字节 短的 单身的 细绳 整数 超长 用户自定义 我们短

Source

目前,我正在尝试创建一个从给定对象生成平面图的函数,因为我正在尝试将对象序列化为 JSON。我正在使用的对象有很多很多循环引用,这些引用总是会破坏 JSON 序列化-r,因为它超出了递归限制。

我的问题:

如果一个对象是“纯”数据类型,我如何使用自省、反射、你有什么、智能地判断?如:对象是布尔值、字节字符等,不是简单地从布尔字节或字符等继承的对象。

我的推理:

我希望完成的是,当我递归遍历给定对象并从中生成平面结构时,我可以保留列表中的对象引用,并“跳过”我已经拥有的对象点击,然后分配那些Guids。 Guid 将与对象的引用一起存在于 JSON 中,但出于所有意图和目的(从 JSON serialize-r 方面),循环引用将被破坏,允许它进行序列化。

但是,字符串、布尔值、空值之类的东西在 JSON 中很容易描述。有没有办法检查我是否已经对对象进行了编目,同时检查对象是否是“纯数据类型”?澄清一下,即使我已经遇到对这些项目的引用,我仍然想将字符串、整数、布尔值、空值写入 JSON。

我也愿意接受替代解决方案或更好的想法。我正试图更好地解决这个问题。提前致谢!

【问题讨论】:

  • ObjectUser-Defined 是否属于您认为的“纯数据类型”?如果不是,那么这根本不应该是一个问题。所有标准数据类型(String 除外)都是结构。在 .NET 中,结构不能被继承,所以 不能 有一种类型 “简单地从布尔字节或字符等继承”,因此可以很好地检查它直截了当。至于String,它被声明为NotInheritable,所以那里也不能继承。
  • 附注,而不是递归迭代我认为是链表结构的父/子节点,您是否考虑过使用 Stack(Of T) 来代替?
  • 在这里查看 Eric Lippert 的回答:stackoverflow.com/questions/11830174/…
  • @ParrishHusband 我没有考虑堆栈实现,不。我也会调查一下。谢谢你的好信息。
  • @VisualVincent 为了缩小主题范围,ObjectUser-Defined 不是我认为的纯数据类型。我想向稍后查看该问题的任何人说明这一点。

标签: json vb.net types


【解决方案1】:

不将ObjectUser-Defined 算作“纯类型”,.NET Framework Type class 实际上包含一个属性,该属性将只为(大部分)构建-输入类型:Type.IsPrimitive.

Primitive(意思是 basicsimple)是指代表单个值的独立基本类型:它们要么是单个数字(IntegerLongShort 等)、单个字符 (Char) 或单个位 (Boolean)。因此,您可以检查Type.IsPrimitive 属性来快速确定当前对象是否是CLR 中定义的任何数值类型(加上Char)。

If myObj.GetType().IsPrimitive Then

好消息是 .NET Framework 不允许继承结构,因此您永远不会遇到继承自 Boolean 的类型。

现在您只需要检查剩余的非原始类型(它们也不能被继承)并且您应该拥有所需的一切:

  • Date
  • Decimal
  • String

您需要做的就是:

Dim objType As Type = myObj.GetType()
If objType.IsPrimitive OrElse
    objType Is GetType(String) OrElse
     objType Is GetType(Date) OrElse
      objType Is GetType(Decimal) Then

你有它!

我建议将其转换为 Extension Method 以方便使用:

Imports System.Runtime.CompilerServices

Public Module Extensions

    <Extension()>
    Public Function IsPureType(ByVal Obj As Object) As Boolean
        If Obj Is Nothing Then Return False

        Dim objType As Type = Obj.GetType()
        Return objType.IsPrimitive OrElse
                objType Is GetType(String) OrElse
                 objType Is GetType(Date) OrElse
                  objType Is GetType(Decimal)
    End Function
End Module

然后你可以像这样使用它:

If myObj.IsPureType() Then


编辑

Jimi pointed out,您可以继承 TypeDelegator 并覆盖 IsPrimitiveImpl 函数,该函数允许您(作为程序员)指定您的自定义类型是否为原始类型。

但是,在我的任何一个测试中,我都无法让Obj.GetType().IsPrimitive 为我的自定义类返回True。这大概是因为Obj.GetType() 为您的自定义类返回了自动生成的RuntimeType,而不是 TypeDelegator,所以不必担心。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2010-12-11
  • 2010-11-13
  • 1970-01-01
  • 2017-01-06
  • 2014-11-22
  • 2011-06-11
  • 2019-01-24
  • 2013-06-02
相关资源
最近更新 更多