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

时间:2011-05-09 04:41:24

标签: c# .net reflection types

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

当您使用具有一些属性的简单类时,我的代码很有效(按预期)。

我想让List<t>到CSV转换器也接受系统类型,如String和Integer。使用这些系统类型,我不想获得它们的公共属性(例如Length,Chars等)。因此,我想检查对象是否是系统类型。按系统类型我的意思是内置的.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是否为内置系统类型? (假设我们不知道它的字符串)

8 个答案:

答案 0 :(得分:51)

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

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

答案 1 :(得分:38)

myName.GetType().Namespace
如果它是内置类型,则返回System。

答案 2 :(得分:10)

如果您无法准确定义“内置系统类型”是什么,那么您可能不会知道给出的任何答案中的类型。更可能你想要做的只是列出你不想做的类型。有一个“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。

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

另见How To Test if Type is Primitive

答案 3 :(得分:4)

我认为这是最好的可能性:

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

答案 4 :(得分:4)

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

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

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;

答案 5 :(得分:3)

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

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

注意:{。{1}}属性仅在.NetFramework&gt;存在时才存在。 4

我很可能会去;以上答案中的以下内容。

  

myName.GetType()。Module.ScopeName ==&#34; CommonLanguageRuntimeLibrary&#34;

但是,经过几次调整;例如,将其作为IsSecurityCritical上的扩展方法,并使用Type作为 CommonLanguageRuntimeLibrary

答案 6 :(得分:0)

鉴于现有答案的警告,我将建议仅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));
}

大概在其他受支持的操作系统上也有类似的路径。

答案 7 :(得分:0)

我喜欢

colType.FullName.StartsWith("System")

而不是

colType.Namespace.StartsWith("System")

因为Namespace可能为空。