Определение того, является ли тип анонимным типом

В С# 3.0 можно ли определить, является ли экземпляр Type анонимным типом?

Ответ 1

Несмотря на то, что анонимный тип является обычным типом, вы можете использовать некоторые эвристики:

public static class TypeExtension {

    public static Boolean IsAnonymousType(this Type type) {
        Boolean hasCompilerGeneratedAttribute = type.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Count() > 0;
        Boolean nameContainsAnonymousType = type.FullName.Contains("AnonymousType");
        Boolean isAnonymousType = hasCompilerGeneratedAttribute && nameContainsAnonymousType;

        return isAnonymousType;
    }
}

Другая хорошая эвристика, которая будет использоваться, - это если имя класса является допустимым именем С# (анонимный тип генерируется без действительных имен классов С# - используйте для этого регулярное выражение).

Ответ 2

Свойства анонимного типизированного объекта

  • имеет пространство имен, равное null
  • базовый тип System.Object
  • IsSealed = true
  • Пользовательский атрибут 0 - DebuggerDisplayAttribute, Тип: ""
  • IsPublic = false

Для моего конкретного приложения, если пространство имен имеет значение null, можно сделать вывод, что тип анонимный, поэтому проверка того, что пространство имен является нулевым, вероятно, является наименее дорогостоящим.

Ответ 3

Не существует языковой конструкции С#, которая позволяет вам сказать: "Это анонимный тип". Вы можете использовать простую эвристику для аппроксимации, если тип является анонимным, но его можно обмануть с помощью персонального кодирования IL или с использованием языка, на котором такие символы, как > и < действительны в идентификаторах.

public static class TypeExtensions {
  public static bool IsAnonymousType(this Type t) {
    var name = t.Name;
    if ( name.Length < 3 ) {
      return false;
    }
    return name[0] == '<' 
        && name[1] == '>' 
        && name.IndexOf("AnonymousType", StringComparison.Ordinal) > 0;
}

Ответ 4

В метаданных и CLR нет таких терминов, как анонимные типы. Анонимные типы - это единственная функция компиляции.

Ответ 5

Может быть полезно знать, почему вы хотите это знать. Если вы выполните следующее:

var myType = new { Name = "Bill" };
Console.Write( myType.GetType().Name  );

... вы увидите что-то вроде "< > f__AnonymousType0`1" как имя типа. В зависимости от ваших требований вы можете предположить, что тип, начинающийся с < > , содержащий "AnonymousType" и символ обратной кавычки, является тем, что вы ищете.

Ответ 6

Кажется, анонимные типы получают DebuggerDisplayAttribute на них, где Type = "<Anonymous Type>".

Изменить: Но только при компиляции в режиме отладки. Чёрт.