How do I tell if a type is a “simple” type? i.e. holds a single value

后端 未结 7 1937
北荒
北荒 2020-12-01 02:46
typeof(string).IsPrimitive == false
typeof(int).IsPrimitive == true
typeof(MyClass).IsClass == true
typeof(string).IsClass == true
typeof(string).IsByRef == false
ty         


        
相关标签:
7条回答
  • 2020-12-01 02:58

    It may not matter, but it sounds like you're leaving out a few cases:

    1. Complex types which have conversions
    2. Value types which don't have a parameterless constructor. Example below:

    There are probably more, but I think you're partitioning the problem space in an overly-restrictive manner.

     public class Person {
        private string _name;
        private int _age;
        public Person(string name, int age) {_name = name; _age = age;}
        // Remainder of value implementation
     }
    
    0 讨论(0)
  • 2020-12-01 03:03

    In Addition to Stefan Steinegger answer: In .NET Core the .IsPrimitive etc. are no longer members of Type, they are now members of TypeInfo. So his solution will then become:

    bool IsSimple(TypeInfo type)
    {
        if (type.IsGenericType && type.GetGenericTypeDefinition() ==     typeof(Nullable<>))
        {
            // nullable type, check if the nested type is simple.
            return IsSimple((type.GetGenericArguments()[0]).GetTypeInfo());
        }
        return type.IsPrimitive
          || type.IsEnum
          || type.Equals(typeof(string))
          || type.Equals(typeof(decimal));
    }
    
    0 讨论(0)
  • 2020-12-01 03:04

    Strings aren't primitives, if I recall correctly. even though there is a keyword for it, a string is an object. Your call to IsPrimitive will accurately tell you if something is a primitive.

    0 讨论(0)
  • 2020-12-01 03:05

    Sorry to resurrect a really old thread, but since this still ranks high on web searches in Google, want to get a more direct and effective solution added:

    if(System.Type.GetTypeCode(typeof(int)) == TypeCode.Object) {
        // Do what you will...
    }
    
    0 讨论(0)
  • 2020-12-01 03:12

    Modified Mauser's answer a little bit added a method to check whether a property is an collection.

    public static class TypeExtensions
    {
        public static bool IsComplex(this Type type)
        {
            return !type.IsValueType && type != typeof(string);
        }
    
        public static bool IsCollection(this Type type)
        {
            var collectionTypeName = typeof(ICollection<>).Name;
            return type.Name == collectionTypeName || type.GetInterface(collectionTypeName) != null;
        }
    }
    

    Here inside IsCollection(..) we can even keep IEnumerable, but string also inherit IEnumerable. so if you are using IEnumerable, add a check for string also!

    public static class TypeExtensions
        {
    
            public static bool IsComplex(this Type type)
            {
                return !type.IsValueType && type != typeof(string);
            }
    
    
    
            public static bool IsCustomComplex(this Type type)
            {
                var elementType = type.GetCustomElementType();
                return elementType != null && elementType.IsComplex();
            }
    
            public static Type GetCustomElementType(this Type type, object value)
            {
                return value != null 
                    ? value.GetType().GetCustomElementType() 
                    : type.GetCustomElementType();
            }
    
            public static Type GetCustomElementType(this Type type)
            {
                return type.IsCollection()
                    ? type.IsArray
                        ? type.GetElementType()
                        : type.GetGenericArguments()[0]
                    : type;
            }
    
    
            public static bool IsCustomComplex(this Type type, object value)
            {
                return value != null
                    ? value.GetType().IsCustomComplex()
                    : type.IsCustomComplex();
            }
    
    
            public static bool IsCollection(this Type type)
            {
                var collectionTypeName = typeof(IEnumerable<>).Name;
                return (type.Name == collectionTypeName || type.GetInterface(typeof(IEnumerable<>).Name) != null ||
                        type.IsArray) && type != typeof(string);
            }
    
            public static bool HasDefaultConstructor(this Type type)
            {
                return type.IsValueType || type.GetConstructor(Type.EmptyTypes) != null;
            }
    
        }
    
    0 讨论(0)
  • 2020-12-01 03:18

    There is a more general type than primitive, the ValueType encompasses a lot more than primitive, such as enums, decimal, and other such things ValueType. Below is a function I wrote to identify complex types, that may fit your needs.

        public static bool IsComplex(Type typeIn)
        {
            if (typeIn.IsSubclassOf(typeof(System.ValueType)) || typeIn.Equals(typeof(string))) //|| typeIn.IsPrimitive
                return false;
            else
                return true;
    
        }
    
    0 讨论(0)
提交回复
热议问题