如何测试一个类型是不是是匿名的? [复制]

Posted

技术标签:

【中文标题】如何测试一个类型是不是是匿名的? [复制]【英文标题】: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
    

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

谢谢

【问题讨论】:

【参考方案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

【讨论】:

来源jclaes.blogspot.com/2011/05/checking-for-anonymous-types.html 遗憾的是,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));

以上是关于如何测试一个类型是不是是匿名的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

动态创建匿名类型? [复制]

如何检查 C# 中的动态匿名类型上是不是存在属性?

有没有办法测试闭包是不是也是生成器?

单元测试 | 如何在Mock时匹配匿名类型参数

确定类型是不是为匿名类型

使用具有匿名类型的 OkNegotiatedContentResult 对 IHttpActionResult 进行单元测试