How To Test if a Type is Anonymous?

19,622

Solution 1

From http://www.liensberger.it/web/blog/?p=191:

private static bool CheckIfAnonymousType(Type type)
{
    if (type == null)
        throw new ArgumentNullException("type");

    // HACK: The only way to detect anonymous types right now.
    return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
        && type.IsGenericType && type.Name.Contains("AnonymousType")
        && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
        && type.Attributes.HasFlag(TypeAttributes.NotPublic);
}

EDIT:
Another link with extension method: Determining whether a Type is an Anonymous Type

Solution 2

Quick and dirty:

if(obj.GetType().Name.Contains("AnonymousType"))

Solution 3

You can just check if the namespace is null.

public static bool IsAnonymousType(this object instance)
{

    if (instance==null)
        return false;

    return instance.GetType().Namespace == null;
}

Solution 4

Well, today compiier generates anonymous types as generic AND sealed classes. A paradoxal combination since specialization of a generic class is a kind of inheritance, isn't? So you can check for this: 1. Is this a generic type? Yes => 2) is its definition sealed && not public? Yes => 3) is its definition has CompilerGeneratedAttribute attribute? I guess, if these 3 criteria are true together, we have an anonymous type... Well... There is a problem with ANY of methods described - they are use aspects that may change in next versions of .NET and it will be so until Microsoft will add IsAnonymous boolean property to Type class. Hope it will happen before we all die... Until that day, it can be checked like so:

using System.Runtime.CompilerServices;
using System.Reflection;

public static class AnonymousTypesSupport
{
    public static bool IsAnonymous(this Type type)
    {
        if (type.IsGenericType)
        {
            var d = type.GetGenericTypeDefinition();
            if (d.IsClass && d.IsSealed && d.Attributes.HasFlag(TypeAttributes.NotPublic))
            {
                var attributes = d.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
                if (attributes != null && attributes.Length > 0)
                {
                    //WOW! We have an anonymous type!!!
                    return true;
                }
            }
        }
        return false;
    }

    public static bool IsAnonymousType<T>(this T instance)
    {
        return IsAnonymous(instance.GetType());
    }
}

Solution 5

Check for CompilerGeneratedAttribute and DebuggerDisplayAttribute.Type

here is the code generated by the compiler for an anomymous type

[CompilerGenerated, DebuggerDisplay(@"\{ a = {a} }", Type="<Anonymous Type>")]
internal sealed class <>f__AnonymousType0<<a>j__TPar>
{
...
}
Share:
19,622
DaveDev
Author by

DaveDev

Updated on June 01, 2022

Comments

  • DaveDev
    DaveDev almost 2 years

    I have the following method which serialises an object to a HTML tag. I only want to do this though if the type isn't Anonymous.

    private void MergeTypeDataToTag(object typeData)
    {
        if (typeData != null)
        {
            Type elementType = typeData.GetType();
    
            if (/* elementType != AnonymousType */)
            {
                _tag.Attributes.Add("class", elementType.Name);    
            }
    
            // do some more stuff
        }
    }
    

    Can somebody show me how to achieve this?

    Thanks

  • serhio
    serhio over 12 years
  • sandeep pathak
    sandeep pathak over 12 years
    Sadly this is false for new{}.GetType() But i think && type.IsGenericType can savely be removed.
  • albertjan
    albertjan almost 11 years
    does this work for mono?
  • João Bragança
    João Bragança over 10 years
    Only works when compiling in debug mode.
  • Davi Fiamenghi
    Davi Fiamenghi over 10 years
    I'm very tempted to click +1. Must not click!! xD
  • Nathan
    Nathan almost 10 years
    There are cases where this does not hold true. I'm not sure of all cases where this fails, but one example is where a lambda expression is used within a protected concrete method of an abstract class with generic parameters. I'm sure there are simpler cases that would also fail.
  • Serguei Fedorov
    Serguei Fedorov almost 9 years
    Dirty and slow unfortunately.
  • Justin Caldicott
    Justin Caldicott almost 9 years
    Looks like you need (type.Name.Contains("AnonymousType") || type.Name.Contains("AnonType")) to be compatible with Mono. Source: NancyFx extension method
  • Francesco Bonizzi
    Francesco Bonizzi over 7 years
    Now it's 2016, do someone know if is there some new possible implementation?
  • BjarkeCK
    BjarkeCK almost 7 years
    @DalSoft Place any class outside a namespace and there you go, which is actually common in some frameworks.
  • BjarkeCK
    BjarkeCK almost 7 years
    @DalSoft Woot^^ I wonder if this is the case in mono as well. Testing..
  • BjarkeCK
    BjarkeCK almost 7 years
    @DalSoft It's null in Mono 2.0
  • BjarkeCK
    BjarkeCK almost 7 years
    @DalSoft Ah, you made a woops. You tested if typeof(Type)'s namespace was null. Fixed: rextester.com/BOL44171 (true, true)
  • DalSoft
    DalSoft almost 7 years
    Woops sorry was having a bad day yesterday - good to know. So in terms of using this then I guess it's a couple of lines for most use cases, or pick a more verbose solution if you need to catch all cases.
  • Admin
    Admin over 6 years
    (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic is trivially always true, because TypeAttributes.NotPublic == 0. This check should be done with TypeAttributes.Public.
  • Ibrahim ben Salah
    Ibrahim ben Salah over 6 years
    Works in release mode too!. var anonType = new {a = 1, b = 2}.GetType(); anonType.CustomAttributes.Select(e => e.AttributeType).Should().Contain(typeof(CompilerGeneratedAt‌​tribute));
  • Daniel Williams
    Daniel Williams about 5 years
    I like this one because it's very simple and should only error in the pathological case where someone has created class with "AnonymousType" in the name, but the object is not actually an anonymous type. That hypothetical someone should be hypothetically flogged.