如何测试类型是否是匿名的?

Dav*_*Dev 63 c# reflection anonymous-types

我有以下方法将对象序列化为HTML标记.如果类型不是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
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我如何实现这一目标吗?

谢谢

Sun*_*nny 63

来自: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);
}
Run Code Online (Sandbox Code Playgroud)

HTH.

编辑:
与扩展方法的另一个链接:确定类型是否是匿名类型

  • (type.Attributes&TypeAttributes.NotPublic)== TypeAttributes.NotPublic通常是真的,因为TypeAttributes.NotPublic == 0。该检查应通过`TypeAttributes.Public`完成。 (3认同)
  • 来自http://jclaes.blogspot.com/2011/05/checking-for-anonymous-types.html (2认同)
  • 遗憾的是,这对于`new {}来说是错误的.GetType()`但我认为`&& type.IsGenericType`可以省去. (2认同)
  • 看起来你需要`(type.Name.Contains("AnonymousType")|| type.Name.Contains("AnonType"))``与Mono兼容.来源:[NancyFx扩展方法](https://github.com/NancyFx/Nancy/blob/master/src/Nancy/ViewEngines/Extensions.cs) (2认同)
  • 现在是2016年,有人知道是否有一些新的可能的实现? (2认同)

Bja*_*eCK 15

又快又脏:

if(obj.GetType().Name.Contains("AnonymousType"))
Run Code Online (Sandbox Code Playgroud)

  • 我非常想点击+1.一定不要点击!的xD (3认同)
  • 我喜欢这个,因为它非常简单,并且只会在有人创建名称为“AnonymousType”的类的病理情况下出错,但该对象实际上不是匿名类型。假设某人应该被鞭打。 (2认同)

Dal*_*oft 9

您只需检查命名空间是否为空.

public static bool IsAnonymousType(this object instance)
{

    if (instance==null)
        return false;

    return instance.GetType().Namespace == null;
}
Run Code Online (Sandbox Code Playgroud)

  • @DalSoft将任何类放在命名空间之外,然后转到那里,这实际上在某些框架中很常见。 (3认同)

Kon*_*aev 7

好吧,今天compiier生成匿名类型作为通用AND密封类.一个矛盾的组合,因为泛型类的特化是一种继承,不是吗?所以你可以检查一下:1.这是一般类型吗?是=> 2)它的定义是否密封&&不公开?是=> 3)它的定义是否具有CompilerGeneratedAttribute属性?我想,如果这三个标准一起成立,我们就会有一个匿名类型......嗯......所描述的任何方法都存在问题 - 它们使用的方面可能会在下一版本的.NET中发生变化,它将会是所以,直到Microsoft将IsAnonymous布尔属性添加到Type类.希望它会在我们都死之前发生......直到那一天,它可以像这样检查:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)


Cat*_*ICU 5

检查CompilerGeneratedAttributeDebuggerDisplayAttribute.Type

这是编译器为非同类型生成的代码

[CompilerGenerated, DebuggerDisplay(@"\{ a = {a} }", Type="<Anonymous Type>")]
internal sealed class <>f__AnonymousType0<<a>j__TPar>
{
...
}
Run Code Online (Sandbox Code Playgroud)

  • 仅在调试模式下编译时有效. (2认同)