确定类型是否为纯“数据类型”

时间:2018-08-16 20:35:46

标签: json vb.net types

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

  

布尔值   字节   烧焦   日期   小数   双   整数   长   宾语   字节数   短   单   串   UInteger   乌龙   用户自定义   美国hort

Source

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

我的问题:

如果对象是“纯”数据类型,我该如何智能地使用内省,反思和发现?如:对象是布尔值,字节字符等,不是仅从布尔字节或字符等继承的对象。

我的推理:

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

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

我也乐于接受替代解决方案或更好的主意。我试图更好地解决这个问题。预先感谢!

1 个答案:

答案 0 :(得分:5)

不将ObjectUser-Defined视为“纯类型” ,. NET Framework Type class实际上包括一个将返回True的属性仅适用于(大多数)内置类型:Type.IsPrimitive

原始(表示 basic simple )是指表示单个值的独立基本类型:它们是单个数字(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,所以不必担心。