2010-03-20 120 views
48

我有以下方法将对象序列化为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 
    } 
} 

有人可以告诉我如何做到这一点?

感谢

回答

53

从代码: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 & TypeAttributes.NotPublic) == TypeAttributes.NotPublic; 
} 

HTH。

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

+2

来自http://jclaes.blogspot.com/2011/05/checking-for-anonymous-types.html – serhio 2011-09-06 12:28:18

+1

不幸的是这是'new {}的错误。GetType()' 但我想'&&类型。 IsGenericType'可以保存被删除。 – 2011-09-14 16:15:59

+2

看起来像你需要'(type.Name.Contains(“AnonymousType”)|| type.Name.Contains(“AnonType”))'与Mono兼容。来源:[NancyFx扩展方法](https://github.com/NancyFx/Nancy/blob/master/src/Nancy/ViewEngines/Extensions.cs) – 2015-07-24 10:33:44

5

检查CompilerGeneratedAttributeDebuggerDisplayAttribute.Type

这里是由编译器生成的anomymous型

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

仅在调试模式下编译时才有效。 – 2013-08-22 18:56:05

+0

也可以在发布模式下工作! var anonType = new {a = 1,b = 2} .GetType(); anonType.CustomAttributes.Select(e => e.AttributeType).Should()。Contain(typeof(CompilerGeneratedAttribute)); – 2017-12-10 16:31:54

12

快速和肮脏的:

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

我很想尝试点击+1。一定不要点击! xD – 2014-01-06 01:42:58

+1

不幸的是,它很脏并且很慢。 – 2015-05-14 20:22:57

6

好了,今天compiier产生匿名类型为通用的,密封类。由于泛型类的特化是一种继承,所以不是一种矛盾的组合? 所以你可以检查这个: 1.这是一个通用类型? 是=> 2)是其定义密封& &不公开? 是=> 3)其定义是否具有CompilerGeneratedAttribute属性? 我想,如果这三个标准是真的在一起,我们有一个匿名类型... 嗯...所描述的任何方法都有问题 - 它们是可能在下一版本的.NET中改变的使用方面直到微软将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()); 
    } 
} 
8

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

public static bool IsAnonymousType(this object instance) 
{ 

    if (instance==null) 
     return false; 

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

这是否适用于单声道? – albertjan 2013-05-23 09:38:35

+0

有些情况下,这不适用。我不确定所有这些失败的情况,但是一个例子是在具有泛型参数的抽象类的受保护具体方法中使用lambda表达式的情况。我确信有更简单的情况也会失败。 – Nathan 2014-05-06 21:32:06

+1

从来没有见过这种失败,我相信这是用于SimpleData匿名检测。请提供一个实际上失败的代码示例。 – DalSoft 2014-05-14 18:40:48