如何确定对象类型是否为内置系统类型
本文关键字:类型 内置 系统 是否 对象 何确定 | 更新日期: 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
可能为空。