I want to distinctly determine if the type that I have is of custom class type (MyClass) or one provided by the Framework (System.String).
Is there any way in reflection that I can distinguish my class type from system.string or other Framework provided types?
The only way to safely check if a type is part of an assembly is to check the assembly's fully qualified name which contains its name, version, culture and public key (if signed). All .Net base class libraries (BCL) are signed by microsoft using their private keys. This makes it almost impossible for anyone else to create an assembly with same fully qualified name as a base class library.
//add more .Net BCL names as necessary
var systemNames = new HashSet<string>
{
"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
};
var isSystemType = systemNames.Contains(objToTest.GetType().Assembly.FullName);
A slightly less brittle solution is to use the AssemblyName class and skip the version number/culture check. This of course assumes the public key doesn't change between versions.
//add more .Net BCL names as necessary
var systemNames = new List<AssemblyName>
{
new AssemblyName ("mscorlib, Version=4.0.0.0, Culture=neutral, " +
"PublicKeyToken=b77a5c561934e089"),
new AssemblyName ("System.Core, Version=4.0.0.0, Culture=neutral, "+
"PublicKeyToken=b77a5c561934e089")
};
var obj = GetObjectToTest();
var objAN = new AssemblyName(obj.GetType().Assembly.FullName);
bool isSystemType = systemNames.Any(
n => n.Name == objAN.Name
&& n.GetPublicKeyToken().SequenceEqual(objAN.GetPublicKeyToken()));
Most of the BCL have been signed with the same key but not all. You could use the AssemblyName class to just check the public key token. It depends on your needs.
If you simply want to distinguish between MyClass
and string
then you can check for those types directly:
Type typeToTest = GetTypeFromSomewhere();
if (typeToTest == typeof(MyClass))
MyClassAction();
else if (typeToTest == typeof(string))
StringAction();
else
NotMyClassOrString();
If you need a more general check for whether or not a given type is a framework type then you could check whether it belongs to the System
namespace:
// create an array of the various public key tokens used by system assemblies
byte[][] systemTokens =
{
typeof(System.Object)
.Assembly.GetName().GetPublicKeyToken(), // B7 7A 5C 56 19 34 E0 89
typeof(System.Web.HttpRequest)
.Assembly.GetName().GetPublicKeyToken(), // B0 3F 5F 7F 11 D5 0A 3A
typeof(System.Workflow.Runtime.WorkflowStatus)
.Assembly.GetName().GetPublicKeyToken() // 31 BF 38 56 AD 36 4E 35
};
Type typeToTest = GetTypeFromSomewhere();
string ns = typeToTest.Namespace;
byte[] token = typeToTest.Assembly.GetName().GetPublicKeyToken();
bool isSystemType = ((ns == "System") || ns.StartsWith("System."))
&& systemTokens.Any(t => t.SequenceEqual(token));
You can check the Assembly in which the type is declared.
object.GetType().Assembly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With