如何确定对象类型是否为内置系统类型

本文关键字:类型 内置 系统 是否 对象 何确定 | 更新日期: 2023-09-27 17:55:22

我正在编写一个简单的List<t>到CSV转换器。我的转换器检查列表中的所有t,并获取所有公共属性并将它们放入 CSV 中。

当您使用具有一些属性的简单类时,我的代码运行良好(如预期的那样)。

我想让List<t> 到 CSV 转换器也接受字符串和整数等系统类型。对于这些系统类型,我不想获取它们的公共属性(例如长度,字符等)。因此,我想检查该对象是否是系统类型。通过系统类型,我的意思是内置的.Net类型之一,例如string, int32, double等。

使用 GetType(),我可以找到以下内容:

string myName = "Joe Doe";
bool isPrimitive = myName.GetType().IsPrimitive; // False
bool isSealed = myName.GetType().IsSealed; // True 
// From memory all of the System types are sealed.
bool isValueType = myName.GetType().IsValueType; // False
// LinqPad users: isPrimitive.Dump();isSealed.Dump();isValueType.Dump();

如何查找变量 myName 是否为内置系统类型?(假设我们不知道它是一个字符串)

如何确定对象类型是否为内置系统类型

以下是几种可能性中的几种:

  • myName.GetType().Namespace == "System"
  • myName.GetType().Namespace.StartsWith("System")
  • myName.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"

myName.GetType().Namespace
如果它是内置类型,这将返回系统。

如果您无法准确定义"内置系统类型"是什么,那么您似乎不知道任何给定的答案中有哪些类型。更可能你想做的只是有一个你不想这样做的类型列表。有一个"IsSimpleType"方法,它只对各种类型进行检查。

您可能正在寻找的另一件事是基元类型。如果是这样,请查看:

Type.IsPrimitive (http://msdn.microsoft.com/en-us/library/system.type.isprimitive.aspx)

基元类型是布尔型、字节型、SByte、Int16、UInt16、Int32、 UInt32、Int64、UInt64、IntPtr、UIntPtr、char、double 和 single。

这不包括字符串,但您可以手动添加它...

另请参阅如何测试类型是否为基元

基于命名空间的方法可能会导致冲突。

还有另一种可靠且简单的方法:

static bool IsSystemType(this Type type) => type.Assembly == typeof(object).Assembly;

或者更优化一点,缓存系统程序集:

static readonly Assembly SystemAssembly = typeof(object).Assembly;
static bool IsSystemType(this Type type) => type.Assembly == SystemAssembly;
我认为这是

最好的可能性:

private static bool IsBulitinType(Type type)
{
    return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object);
}

我正在反思性地构建一些东西,发现IsSecurityCritical属性似乎适用于此目的;但是,这只是因为我的程序集的信任级别不够高,无法翻转该位。

有点笑;谢天谢地,我发现了这个问题,并将做出相应的调整。

: 仅当 时,IsSecurityCritical属性才存在。网络框架> 4

我可能会接受;以下来自之前的答案。

myName.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"

但是,做了一些调整;例如使其成为Type上的扩展方法,并为CommonLanguageRuntimeLibrary使用const

鉴于围绕现有答案的警告,我将建议一个仅限Windows的解决方案:

public static class TypeExt {
    public static bool IsBuiltin(this Type aType) => new[] { "/dotnet/shared/microsoft", "/windows/microsoft.net" }.Any(p => aType.Assembly.CodeBase.ToLowerInvariant().Contains(p));
}

据推测,在其他受支持的操作系统上也有类似的路径。

我更喜欢

colType.FullName.StartsWith("System")

而不是然后

colType.Namespace.StartsWith("System")

becose Namespace 可能为空。