There have been several questions on StackOverflow about how to determine if a type is defined in the .NET Framework or is a third-party or custom type. Based on the answers provided to these questions, this can be accomplished using some reflection to retrieve the public key token of the .NET assembly in which the type is defined and compare it to a public key token known to be used by Microsoft to sign the .NET Framework assemblies.
To do this, you can make use of the following extension method:
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 all versions of the .NET Framework starting with .NET Framework 2.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 extension method like:
Debug.WriteLine("Is type `string` a .NET Framework type? {0}",
typeof(string).IsFrameworkType());