【问题标题】:How To Test if a Type is Anonymous? [duplicate]如何测试一个类型是否是匿名的? [复制]
【发布时间】:2011-01-29 19:03:45
【问题描述】:

我有以下将对象序列化为 HTML 标记的方法。我只想在类型不是匿名的情况下这样做。

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
    }
}

谁能告诉我如何做到这一点?

谢谢

【问题讨论】:

    标签: c# reflection anonymous-types


    【解决方案1】:

    来自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);
    }
    

    编辑:
    另一个带有扩展方法的链接:Determining whether a Type is an Anonymous Type

    【讨论】:

    • 遗憾的是,new{}.GetType() 是错误的,但我认为 &amp;&amp; type.IsGenericType 可以被删除。
    • 看来您需要(type.Name.Contains("AnonymousType") || type.Name.Contains("AnonType")) 才能与 Mono 兼容。来源:NancyFx extension method
    • 现在是 2016 年,有人知道是否有一些新的可能实现吗?
    • (type.Attributes &amp; TypeAttributes.NotPublic) == TypeAttributes.NotPublic 总是正确的,因为TypeAttributes.NotPublic == 0。此检查应使用TypeAttributes.Public 完成。
    【解决方案2】:

    又快又脏:

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

    【讨论】:

    • 我很想点击 +1。千万不要点击!! xD
    • 不幸的是又脏又慢。
    • 我喜欢这个,因为它非常简单,并且只在有人创建了名称中带有“AnonymousType”的类但对象实际上不是匿名类型的病态情况下才会出错。假设某人应该被假设性地鞭打。
    【解决方案3】:

    你可以只检查命名空间是否为空。

    public static bool IsAnonymousType(this object instance)
    {
    
        if (instance==null)
            return false;
    
        return instance.GetType().Namespace == null;
    }
    

    【讨论】:

    • 这对单声道有效吗?
    • 在某些情况下这不成立。我不确定在所有情况下都会失败,但一个示例是在具有泛型参数的抽象类的受保护具体方法中使用 lambda 表达式。我敢肯定还有更简单的情况也会失败。
    • @DalSoft 将任何类放在命名空间之外就可以了,这在某些框架中实际上很常见。
    • @DalSoft Woot^^ 我想知道单声道是否也是如此。测试..
    • @DalSoft 啊,你搞砸了。您测试了 typeof(Type) 的命名空间是否为空。固定:rextester.com/BOL44171(真,真)
    【解决方案4】:

    好吧,今天编译器将匿名类型生成为泛型和密封类。一个自相矛盾的组合,因为泛型类的特化是一种继承,不是吗? 所以你可以检查这个: 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());
        }
    }
    

    【讨论】:

      【解决方案5】:

      检查CompilerGeneratedAttributeDebuggerDisplayAttribute.Type

      这是编译器为异常类型生成的代码

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

      【讨论】:

      • 仅在调试模式下编译时有效。
      • 也可以在发布模式下工作!。 var anonType = new {a = 1, b = 2}.GetType(); anonType.CustomAttributes.Select(e => e.AttributeType).Should().Contain(typeof(CompilerGeneratedAttribute));
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 2017-08-06
      • 2021-12-23
      相关资源
      最近更新 更多