有没有一个函数可以检查一个对象是否是内置数据类型?

5

我想查看一个对象是否是C#中的内置数据类型

如果可能的话,我不想检查所有这些类型。
也就是说,我不想这样做:

        Object foo = 3;
        Type type_of_foo = foo.GetType();
        if (type_of_foo == typeof(string))
        {
            ...
        }
        else if (type_of_foo == typeof(int))
        {
            ...
        }
        ...

更新

我正在尝试递归创建一个 PropertyDescriptorCollection,其中 PropertyDescriptor 类型可能不是内置值。因此,我想做类似于这样的事情(注意:这还没有实现,但我正在努力):

    public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        PropertyDescriptorCollection cols = base.GetProperties(attributes);

        List<PropertyDescriptor> list_of_properties_desc = CreatePDList(cols);
        return new PropertyDescriptorCollection(list_of_properties_desc.ToArray());
    }

    private List<PropertyDescriptor> CreatePDList(PropertyDescriptorCollection dpCollection)
    {
        List<PropertyDescriptor> list_of_properties_desc = new List<PropertyDescriptor>();
        foreach (PropertyDescriptor pd in dpCollection)
        {
            if (IsBulitin(pd.PropertyType))
            {
                list_of_properties_desc.Add(pd);
            }
            else
            {
                list_of_properties_desc.AddRange(CreatePDList(pd.GetChildProperties()));
            }
        }
        return list_of_properties_desc;
    }

    // This was the orginal posted answer to my above question
    private bool IsBulitin(Type inType)
    {
        return inType.IsPrimitive || inType == typeof(string) || inType == typeof(object);
    }
3个回答

9

不能直接实现,但您可以进行以下简化检查

public bool IsBulitin(object o) {
  var type = o.GetType();
  return (type.IsPrimitive && type != typeof(IntPtr) && type != typeof(UIntPtr))
        || type == typeof(string) 
        || type == typeof(object) 
        || type == typeof(Decimal);
}

IsPrimitive检查会捕获除字符串、对象和十进制数外的所有内容。

编辑

虽然这种方法可行,但我更喜欢Jon的解决方案。原因很简单,看一下我必须对我的解决方案进行的编辑次数,因为我忘记了哪些类型是原始类型或不是原始类型。更容易将它们全部明确列出在一个集合中。


1
你还需要检查它是否不是IntPtr,因为它是原始类型但不是内置类型。这就是为什么我对这种方法不是特别热衷的原因 - 你需要比较两个列表并找出差异,而显式集合只意味着从C#规范中逐字复制列表 :) - Jon Skeet
@Jared:因此我评论被删除了 :) (对于那些没有注意到的人,Jared的答案最初没有包括小数。我在他修复时发表了评论...) - Jon Skeet
的确。native int (System.IntPtr) 是一个 .NET 原始类型。 - Mehrdad Afshari
@Jon,抱歉,我忘记了IntPtr。但是证明在编辑中,更容易明确列出它们。 - JaredPar
Guid怎么样? - tocqueville

5

好的,一种简单的方法是在集合中明确列出它们,例如:

static readonly HashSet<Type> BuiltInTypes = new HashSet<Type>
    (typeof(object), typeof(string), typeof(int) ... };

...


if (BuiltInTypes.Contains(typeOfFoo))
{
    ...
}

我必须问一下为什么这很重要 - 我可以理解如果它是.NET原始类型,那么它可能会有所不同,但您能解释一下为什么如果它是C#本身的类型,您希望应用程序的行为有所不同吗?这是为开发工具而设计的吗?
根据这个问题的答案,您可能需要考虑在C# 4中使用dynamic的情况 - 它在执行时不是一种类型,而是一个方法参数等的System.Object + 属性。

我想递归地创建一个 PropertyDescriptorCollection,并且需要检查类型是否为内置类型。如果其中一个属性不是内置类型,我想创建一个新的集合。我会在问题中添加我要尝试做什么,也许这会有所帮助。 - SwDevMan81
但为什么这个决定要基于C#规范呢?你为什么想以不同的方式处理Decimal、DateTime或Guid? - Jon Skeet
那么你是真的只关心它是值类型还是引用类型吗?如果是这样,使用Type.IsValueType。你可能也想将字符串特殊处理一下... - Jon Skeet
很好,是的,这正是我要找的,所以我只需要额外检查字符串和对象对吗? - SwDevMan81
这要看情况——如果只是对象,你真正想做什么?如果类型确实只是对象,那么也没有真正的数据。 - Jon Skeet
显示剩余2条评论

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接