【问题标题】:How to decide a Type is a custom struct?如何确定 Type 是自定义结构?
【发布时间】:2010-02-19 12:44:46
【问题描述】:

对于一个Type,C#中有一个属性IsClass,但是如何判断一个Type是一个结构体呢?

虽然IsValueType是必要条件,但显然还不够。因为int 也是一个值类型。

有人建议以下代码:

bool IsStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive;

但我不确定这是否是一种准确的方法。该公式应该可以区分结构和其他类型,例如DateTimeintarrays。

正如一些朋友指出的,这里我的意思是用户定义的结构而不是预定义的类型,比如DateTime

【问题讨论】:

  • 我不确定我是否理解这个问题。 DateTime is 是一个结构。为什么你会在那里返回 false?
  • 其实 int 也是一个结构体类型。语言规范声明“C# 提供了一组预定义的结构类型,称为简单类型”。
  • 知道你为什么关心会很有趣。你在做什么?可能有更好的方法来做你想做的事。
  • 为什么需要这个功能?我正在使用反射来显示数据。当我遇到一个用户结构时,我会显示它的字段。

标签: c# struct


【解决方案1】:

从技术上讲,int 也是一个结构。 IsPrimitive 只是检查该类型是否是 CLR 处理的基本类型之一,但略有不同。你应该接受IsValueType && !IsEnum && !IsPrimitive的建议。

如果您只想要自定义结构(即 BCL 未提供的结构),您可能会幸运地排除具有以 "System." 开头的 FullName 的类型,或者通过按程序集过滤仅包括您感兴趣的类型或命名空间,或使用自定义属性。

【讨论】:

  • +1 或 "Microsoft.""FSharp." 或 . . .我认为他将很难消除所有这些。
【解决方案2】:

至少应该是

bool isStruct = type.IsValueType && !type.IsEnum &&
               !type.IsPrimitive && type != typeof(decimal);

【讨论】:

    【解决方案3】:

    http://msdn.microsoft.com/en-us/library/bfft1t3c.aspx 说: 如果 Type 为 {bool, byte, char, decimal, double, enum, float, int, long, sbyte, short, struct, uint, ulong, ushort},则 IsValueType 为真。

    http://msdn.microsoft.com/en-us/library/system.type.isprimitive%28v=vs.110%29.aspx 说: 如果 Type 在 {Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single} 中,IsPrimitive 为真。

    对于 IsStruct,您可以使用这样的方法:

    public static bool IsStruct(this Type type)
    {
        return type.IsValueType 
                && !type.IsPrimitive 
                && !type.IsEnum 
                && type != typeof(decimal);
    }
    

    【讨论】:

      【解决方案4】:

      你会遇到困难的。基础框架不知道框架其他部分的所有预定义类型是什么。例如,期望核心框架知道System.Drawing.Point 是不合理的。

      OregonGhost 可能有最好的answer:获取类型信息并检查FullName 属性以查看它是否以"System." 开头。但是您还需要检查"Microsoft.""FSharp",可能还有其他人。只需在 Visual Studio 中单击“添加引用”,然后查看出现的名称。

      然后你可能会冒太多阻塞的风险。 Microsoft 通过 NuGet 包分发一些程序集,这些程序集中的类型通常具有以 "System.""Microsoft." 开头的名称,即使它们没有随框架分发,您是否考虑这些“内置”类型?

      【讨论】:

        【解决方案5】:

        它对我有用 !x.PropertyType.IsSecurityTransparent && x.PropertyType.IsClass

        【讨论】:

          【解决方案6】:

          不是一个完美的解决方案,但您始终可以考虑通过您希望搜索的程序集中的已知类型来缩小搜索范围:

          System.Reflection.Assembly.GetAssembly(tyepof(OneOfMyTypes))
              .GetExportedTypes()
              .Where(t => t.IsValueType);
          

          这有助于消除误报(更安全?),但它的便携性较差。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-10-12
            • 2011-02-12
            • 2011-08-14
            • 2011-01-18
            • 1970-01-01
            • 1970-01-01
            • 2021-10-15
            相关资源
            最近更新 更多