views:

300

answers:

2

I would like to see if an object is a builtin data type in C#

I don't want to check against all of them if possible.
That is, I don't want to do this:

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

Update

I'm trying to recursively create a PropertyDescriptorCollection where the PropertyDescriptor types might not be builtin values. So I wanted to do something like this (note: this doesn't work yet, but I'm working on it):

    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  A: 

Not directly but you can do the following simplified check

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

The IsPrimitive check will catch everything but string, object and decimal.

EDIT

While this method works, I would prefer Jon's solution. The reason is simple, check the number of edits I had to make to my solution because of the types I forgot were or were not primitives. Easier to just list them all out explicitly in a set.

JaredPar
@Jon just sneaked in the update before your comment ;)
JaredPar
You'd also want to check for it *not* being IntPtr, which is primitive but not built-in. That's why I'm not terribly keen on this method - you need to compare the two lists and work out the differences, whereas an explicit set just means copying the list verbatim from the C# spec :)
Jon Skeet
@Jared: Hence the removal of my comment :) (For those who didn't happen to catch it, Jared's answer initially didn't include decimal. I commented while he was fixing it...)
Jon Skeet
Indeed. `native int` (`System.IntPtr`) is a primitive .NET type.
Mehrdad Afshari
@Jon, arg, forgot about IntPtr. But the proof is in the edits, easier to list them out explicitly
JaredPar
+4  A: 

Well, one easy way is to just explicitly list them in a set, e.g.

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

...


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

I have to ask why it's important though - I can understand how it might make a difference if it's a .NET primitive type, but could you explain why you would want your application to behave differently if it's one of the ones for C# itself? Is this for a development tool?

Depending on the answer to that question, you might want to consider the situation with dynamic in C# 4 - which isn't a type at execution time as such, but is System.Object + an attribute when applied to a method parameter etc.

Jon Skeet
I wanted to recursively create a PropertyDescriptorCollection and I needed to check if the type is builtin or not. I wanted to create a new collection if one of the properties was no a builtin type. Ill add what Im trying to do in the question, maybe that will help
SwDevMan81
But why would that decision be based on the C# specification? Why would you want to treat Decimal in one way, but DateTime or Guid in a different way?
Jon Skeet
Right, it should not be, that was an oversight on my part. System.ValueType's should also be checked.
SwDevMan81
So are you *really* just interested in whether it's a value type or a reference type? If so, use Type.IsValueType. You might want to special-case strings as well...
Jon Skeet
Nice, yes thats what I'm looking for, so I only need an extra check for string and object right?
SwDevMan81
Well it depends - what do you really want to do if it's just object? If the type really is just object, there's no real data anyway.
Jon Skeet
Thats true, I guess it wouldnt work for what I am trying to do since the ambiguity of Object x = 3; and Object x = ConcreteObject; would cause things to break. Thanks for the help.
SwDevMan81