Есть ли функция для проверки того, является ли объект встроенным типом данных?

Я хотел бы узнать, является ли объект встроенным типом данных в С#

Я не хочу проверять их все, если это возможно.
То есть я не хочу делать следующее:

        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);
    }

person SwDevMan81    schedule 11.07.2009    source источник


Ответы (3)


Ну, один простой способ - просто явно указать их в наборе, например.

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

...


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

Я должен спросить, почему это важно — я могу понять, как это может иметь значение, если это примитивного типа .NET, но не могли бы вы объяснить, почему вы хотите, чтобы ваше приложение вело себя по-другому, если оно является одним из приложений для самого C#? Это для инструмента разработки?

В зависимости от ответа на этот вопрос вы можете рассмотреть ситуацию с dynamic в C# 4, которая не является типом во время выполнения как таковым, но является System.Object + атрибутом при применении к параметру метода и т. д.

person Jon Skeet    schedule 11.07.2009
comment
Я хотел рекурсивно создать PropertyDescriptorCollection, и мне нужно было проверить, является ли тип встроенным или нет. Я хотел создать новую коллекцию, если одно из свойств не было встроенным типом. Я добавлю, что я пытаюсь сделать в вопросе, может быть, это поможет - person SwDevMan81; 12.07.2009
comment
Но почему это решение должно быть основано на спецификации C#? Почему вы хотите обрабатывать Decimal одним способом, а DateTime или Guid - другим? - person Jon Skeet; 12.07.2009
comment
Верно, этого не должно быть, это была оплошность с моей стороны. Также следует проверить System.ValueType. - person SwDevMan81; 12.07.2009
comment
Итак, вас действительно просто интересует, является ли это типом значения или ссылочным типом? Если это так, используйте Type.IsValueType. Возможно, вы также захотите использовать строки в особом регистре... - person Jon Skeet; 12.07.2009
comment
Хорошо, да, это то, что я ищу, поэтому мне нужна только дополнительная проверка строки и объекта, верно? - person SwDevMan81; 12.07.2009
comment
Ну, это зависит от того, что вы действительно хотите сделать, если это просто объект? Если тип действительно просто объект, реальных данных все равно нет. - person Jon Skeet; 12.07.2009
comment
Это правда, я думаю, это не сработает для того, что я пытаюсь сделать, поскольку неоднозначность объекта x = 3; и Объект x = БетонныйОбъект; приведет к поломке вещей. Спасибо за помощь. - person SwDevMan81; 12.07.2009

Не напрямую, но вы можете сделать следующую упрощенную проверку

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 поймает все, кроме строки, объекта и десятичного числа.

ИЗМЕНИТЬ

Хотя этот метод работает, я бы предпочел решение Джона. Причина проста, проверьте количество правок, которые мне пришлось внести в свое решение из-за того, что типы, которые я забыл, были или не были примитивами. Проще просто перечислить их все явно в наборе.

person JaredPar    schedule 11.07.2009
comment
Вы также хотели бы проверить, не ли это IntPtr, который является примитивным, но не встроенным. Вот почему я не очень в восторге от этого метода — вам нужно сравнить два списка и выяснить различия, тогда как явный набор просто означает дословное копирование списка из спецификации С# :) - person Jon Skeet; 12.07.2009
comment
@Jared: Следовательно, мой комментарий был удален :) (Для тех, кто не уловил его, ответ Джареда изначально не включал десятичную дробь. Я прокомментировал, пока он исправлял это ...) - person Jon Skeet; 12.07.2009
comment
Верно. native int (System.IntPtr) — это примитивный тип .NET. - person mmx; 12.07.2009
comment
@Jon, арг, забыл про IntPtr. Но доказательство в правках, проще перечислить их явно - person JaredPar; 12.07.2009
comment
Как насчет Гида? - person tocqueville; 17.02.2017

Я думаю, что это один из лучших вариантов:

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