Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine and check whether a type in assembly is Custom type or Primitive type using reflection in .NET?

Is it possible to check at runtime whether given type is Custom data type or one of primitive data types of .NET?

I have defined user defined types in assembly and those all types are some structs. I need to call the methods of user defined types of whome parameters are those structs. So this needs to fill the data accordingly before calling those function at runtime using reflection.

Now Is there any method available in reflection by which we can track that given data type is custom or primitive data type. I know about IsClass attribute, but my targeted user defined data types are not classes , these public are STRUCTS.

like image 758
Hassan Avatar asked Sep 04 '10 15:09

Hassan


2 Answers

I'd go with something like:

static bool IsFundamental(this Type type)
{
    return type.IsPrimitive || type.Equals(typeof(string)) || type.Equals(typeof(DateTime));
}

The choice of string and DateTime as additions to the types for which IsPrimitive returns true, though, is a subjective matter since there is no absolute list... the ultimate choice is yours (you might want to include decimal as well, for example); and it should definitely be documented (at least in a comment, preferably an XML one).

like image 68
Dan Tao Avatar answered Oct 25 '22 01:10

Dan Tao


Based on information in this question, you can accomplish this using the following code:

public static class TypeExtensions
{
    private static List<byte[]> tokens = new List<byte[]>() 
    {
        new byte[] {0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89},
        new byte[] {0x31, 0xbf, 0x38, 0x56, 0xad, 0x36, 0x4e, 0x35},
        new byte[] {0xb0, 0x3f, 0x5f, 0x7f, 0x11, 0xd5, 0x0a, 0x3a}
    };

    public static bool IsFrameworkType(this Type type)
    {
        if (type == null) { throw new ArgumentNullException("type"); }

        byte[] publicKeyToken = type.Assembly.GetName().GetPublicKeyToken();    

        return publicKeyToken != null && publicKeyToken.Length == 8
           && tokens.Contains(publicKeyToken, new ByteArrayEqualityComparer());
    }
}

The set of public key tokens are valid for .NET 2.0 and higher (including .NET 4.0). The ByteArrayEqualityComparer class looks like:

public class ByteArrayEqualityComparer : EqualityComparer<byte[]>
{
    public override bool Equals(byte[] x, byte[] y)
    {
        return x != null && y != null
                    && x.Length == 8 && y.Length == 8
                    && x[0] == y[0]
                    && x[1] == y[1]
                    && x[2] == y[2]
                    && x[3] == y[3]
                    && x[4] == y[4]
                    && x[5] == y[5]
                    && x[6] == y[6]
                    && x[7] == y[7];
    }

    public override int GetHashCode(byte[] obj)
    {
        return obj.GetHashCode();
    }
}

You would then use this method like:

Debug.WriteLine("Is type `string` a .NET Framework type? {0}",
   typeof(string).IsFrameworkType());
like image 41
Scott Dorman Avatar answered Oct 25 '22 02:10

Scott Dorman