How do I know if a type is "simple"? those. has a single meaning

typeof(string).IsPrimitive == false typeof(int).IsPrimitive == true typeof(MyClass).IsClass == true typeof(string).IsClass == true typeof(string).IsByRef == false typeof(MyClass).IsByRef == true // correction: should be false (see comments below) 

I have a method that creates an instance of a new instance of T and, if it is a "complex" class, populates its properties from the set of values โ€‹โ€‹of the source data.

(a) If T is a simple type (for example, a string or int or something similar), you need to perform a quick conversion from the original data to T.

(b) If T is a class (but not something as simple as a string), then I will use Activator.CreateInstance and flip it a bit to fill in the fields.

Is there a simple and easy way to say whether I should use method (a) or method (b)? This logic will be used inside the general method with T as a type argument.

+41
generics c #
May 14, '09 at 15:06
source share
6 answers

The string is probably a special case.

I think I will do .....

 bool IsSimple(Type type) { return type.IsPrimitive || type.Equals(typeof(string))); } 



Edit:

Sometimes you need to cover a few more cases, such as enumerations and decimal numbers. Enumerations are a special type of type in C #. Decimal numbers are structures like any other. The problem with structures is that they can be complex, they can be user-defined types, they can be just a number. Thus, you have no other chance than knowing what they should distinguish.

 bool IsSimple(Type type) { return type.IsPrimitive || type.IsEnum || type.Equals(typeof(string)) || type.Equals(typeof(decimal)); } 

Handling zero-matching equivalents is also a bit complicated. Zero-value itself is a structure.

 bool IsSimple(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { // nullable type, check if the nested type is simple. return IsSimple(type.GetGenericArguments()[0]); } return type.IsPrimitive || type.IsEnum || type.Equals(typeof(string)) || type.Equals(typeof(decimal)); } 

Test:

 Assert.IsTrue(IsSimple(typeof(string))); Assert.IsTrue(IsSimple(typeof(int))); Assert.IsTrue(IsSimple(typeof(decimal))); Assert.IsTrue(IsSimple(typeof(float))); Assert.IsTrue(IsSimple(typeof(StringComparison))); // enum Assert.IsTrue(IsSimple(typeof(int?))); Assert.IsTrue(IsSimple(typeof(decimal?))); Assert.IsTrue(IsSimple(typeof(StringComparison?))); Assert.IsFalse(IsSimple(typeof(object))); Assert.IsFalse(IsSimple(typeof(Point))); // struct in System.Drawing Assert.IsFalse(IsSimple(typeof(Point?))); Assert.IsFalse(IsSimple(typeof(StringBuilder))); // reference type 
+79
May 14 '09 at 15:14
source share

In addition to Stefan Steinegger answer: In .NET Core.IsPrimitive, etc. They are no longer members of Type, they are now members of TypeInfo. Therefore, his decision will be as follows:

 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)); } 
+10
Aug 17 '16 at 13:42 on
source share

There is a more general type than a primitive; ValueType includes much more than a primitive, such as enumerations, decimals, and other similar things ValueType . Below is a function that I wrote to define complex types that might suit 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; } 
+4
Aug 13 '15 at 18:55
source share

Sorry to resurrect a really old thread, but since it still appreciates Google web search, you want a more direct and efficient solution:

 if(System.Type.GetTypeCode(typeof(int)) == TypeCode.Object) { // Do what you will... } 
+3
Sep 02 '15 at 21:00
source share

It may not matter, but it looks like you are leaving a few cases:

  • Complex types having conversions
  • Value types that do not have a constructor without parameters. Example below:

There are probably more, but I think you are breaking up the problem space in an overly restrictive way.

  public class Person { private string _name; private int _age; public Person(string name, int age) {_name = name; _age = age;} // Remainder of value implementation } 
+1
May 14, '09 at 15:22
source share

Lines are not primitives, if I remember correctly. although there is a keyword for it, a string is an object. Your call to IsPrimitive will tell you for sure if something is primitive.

0
May 14, '09 at 15:19
source share



All Articles