Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if the type of an object is a type defined by .NET Framework

How can I determine by reflection if the type of an object is defined by a class in my own assembly or by the .NET Framework?

I dont want to supply the name of my own assembly in code, because it should work with any assembly and namespace.

like image 342
Mathias F Avatar asked Jun 07 '09 19:06

Mathias F


People also ask

How do you check if an object is of a certain type C#?

To determine whether an object is a specific type, you can use your language's type comparison keyword or construct. For example, you can use the TypeOf… Is construct in Visual Basic or the is keyword in C#. The GetType method is inherited by all types that derive from Object.

What is TypeOf in C#?

The C# typeof operator ( GetType operator in Visual Basic) is used to get a Type object representing String. From this Type object, the GetMethod method is used to get a MethodInfo representing the String. Substring overload that takes a starting location and a length.

How do you get type objects from assemblies that are already loaded?

Use Type. GetType to get the Type objects from an assembly that is already loaded.

What are .NET types?

NET type is a collection of members, which may be fields (i.e., they hold data of some type), methods (i.e., they contain code), or nested type definitions, and all members have some level of protection (e.g., public, private, protected).


1 Answers

Where would third-party types come in? You might want to differentiate between types which claim to be provided by Microsoft and types which don't.

using System;
using System.Linq;
using System.Reflection;

class Test
{
    static void Main()
    {
        Console.WriteLine(IsMicrosoftType(typeof(string)));
        Console.WriteLine(IsMicrosoftType(typeof(Test)));
    }

    static bool IsMicrosoftType(Type type)
    {
        object[] attrs = type.Assembly.GetCustomAttributes
            (typeof(AssemblyCompanyAttribute), false);

        return attrs.OfType<AssemblyCompanyAttribute>()
                    .Any(attr => attr.Company == "Microsoft Corporation");
    }
}

Of course, any type could claim to be a Microsoft one given this scheme, but if you're actually only going to call it on your own types and framework ones, I suspect this should work fine.

Alternatively, you could use the assembly's public key token. This is likely to be harder to fake. It relies on Microsoft using a common public key for all their assemblies, which they don't (according to Mehrdad's comment below). However, you could easily adapt this solution for a set of accepted "this is from Microsoft" public keys. Perhaps combine the two approaches somehow and report any differences for further inspection...

static bool IsMicrosoftType(Type type)
{
    AssemblyName name = type.Assembly.GetName();
    byte[] publicKeyToken = name.GetPublicKeyToken();

    return publicKeyToken != null
        && publicKeyToken.Length == 8
        && publicKeyToken[0] == 0xb7
        && publicKeyToken[1] == 0x7a
        && publicKeyToken[2] == 0x5c
        && publicKeyToken[3] == 0x56
        && publicKeyToken[4] == 0x19
        && publicKeyToken[5] == 0x34
        && publicKeyToken[6] == 0xe0
        && publicKeyToken[7] == 0x89;
}
like image 123
Jon Skeet Avatar answered Oct 17 '22 08:10

Jon Skeet