Получить свойства чтения/записи анонимного типа

Мне нужно получить все свойства анонимного типа, которые можно записать в.

например:

 var person = new {Name = "Person Name", Age = 25};
 Type anonymousType = person.GetType();
 var properties = anonymousType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

Проблема заключается в том, что все свойства имеют свойство CanWrite false. Это возвращается как истина для не анонимных типов.
Я также попробовал сделать вызов PropertyInfo.GetSetMethod(), который возвращает null.
Как проверить, можно ли записать свойство?

Edit: Возможно, было бы достаточно знать, является ли тип анонимным или нет. Как узнать, является ли тип анонимным с помощью отражения?

Ответ 1

Анонимные типы, сгенерированные из С#, всегда неизменяемы, поэтому набор доступных для записи свойств пуст. В VB это необязательно: каждое свойство по умолчанию является изменяемым, но если вы префикс его с Key, он непреложный; только свойства, объявленные с использованием Key count для генерации равенства и хеш-кода. Лично я предпочитаю подход С#.

CanWrite не всегда возвращается как true для свойств в неанонимных типах - только для записываемых. Свойства могут быть доступны только для чтения, только для записи или чтения-записи. Например:

public class Test
{
    // CanWrite will return false. CanRead will return true.
    public int ReadOnly { get { return 10; } }

    // CanWrite will return true. CanRead will return false.
    public int WriteOnly { set {} }

    // CanWrite will return true. CanRead will return true.
    public int ReadWrite { get { return 10; } set {} }
}

Ответ 2

Нет надежного способа определить, является ли тип анонимным, поскольку среда выполнения .NET 2.0 не поддерживает анонимные типы. Опора на формат "сгенерированного компилятором имени" не является безопасным исправлением, поскольку это может измениться с разными версиями компилятора.

Похоже, вы ответили на свой собственный вопрос: "Как я могу проверить, можно ли написать свойство" с приведенными выше утверждениями: CanWrite - false, а GetSetMethod (true) возвращает null. Это два знака, которые вы не можете записать в собственность.

Поскольку мы находимся в среде выполнения .NET 2.0, в System.Type нет свойства "IsAnonymous", поэтому у вас действительно нет надежного метода для идентификации анонимного типа.

Ответ 3

Свойства анонимных типов не могут быть назначены, поэтому отчеты отражения корректно.

Если вы посмотрите на скомпилированный IL, вы заметите, что, хотя код С# выглядит так, будто он использует обычный инициализатор, он переписывается компилятором как вызов конструктора, который позволяет свойствам не быть -writable вне класса.

Ответ 4

Как узнать, является ли тип анонимным с помощью отражения?

Я думаю, вы можете проверить, имеет ли тип атрибут CompilerGenerated

Ответ 5

Как узнать, является ли тип анонимным с помощью отражения?

Просто используйте этот код.

var isAnonymousType = Attribute.IsDefined(dataType, typeof (CompilerGeneratedAttribute), false) && dataType.IsGenericType && dataType.FullName.Contains("Anonymous") &&  (dataType.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;