2015-09-28 4 views
2

Мне интересно, как получить значение по умолчанию для поля любого произвольного класса.Получить значение по умолчанию для поля

Например,

public class Example 
{ 
    public int a = 10; 
} 

Я хочу, чтобы получить значение 10 когда только typeof(Example) дается.

Это значение по умолчанию полезно, потому что я пишу функцию для создания ненулевого экземпляра по умолчанию для любого типа. Было бы неплохо, если бы экземпляр был инициализирован значениями, указанными в объявлении.

Обратите внимание, что создание экземпляра с помощью конструктора по умолчанию и захват значения не является для меня вариантом, поскольку я надеюсь, что функция, над которой я работаю, может применяться к классам с конструкторами или без конструкторов по умолчанию.

Кроме того, DefaultValueAttribute также не является для меня вариантом. Насколько мне известно, атрибуты могут принимать только несколько типов в качестве аргумента. Поэтому я не могу получить значение по умолчанию для полей самоопределяемых типов.

Edit 1:

Я знаю, этот вопрос, кажется, дублирует Get default value of class member, но это не так. В упомянутом вопросе OP удовлетворен использованием конструктора для получения реального экземпляра класса. Но в моем случае я не могу быть уверен, что конструктор по умолчанию существует для класса, с которым я имею дело.

Я пишу генератор значений по умолчанию, потому что мне нужен поддельный объект произвольного типа. То есть, нет предположения о том, каким будет тип. Поддельный объект будет проверяться с помощью графического интерфейса пользователя, и пользователь может редактировать значения полей, которые отображаются в инспекторе. Здесь произвольный тип важен для меня, потому что инспектор должен работать не только с определенными мной типами, но и с типами, определенными в библиотеках. Более того, поддельный объект никогда не должен быть пустым или инспектор взорвется, LOL.

FormatterServices.GetSafeUninitializedObject получает мне приемлемый поддельный объект, поскольку он выделяет блоки памяти и инициализирует их нулями. Но я чувствую, что было бы лучше, если поддельный объект может быть дополнительно инициализирован, чтобы поля могли иметь значения по умолчанию, указанные в инспекторе.

Благодаря Патрику Хофману мне напоминает, что «значение по умолчанию», о котором я говорю, не является реальным дефолтом, а выражением, которое будет оцениваться в конструкторах. При этом мне все еще интересно, можно ли получить выражение инициализации поля и оценить его событие.

Я думаю, что должен быть способ сделать это, потому что декомпиляторы, такие как ILSpy, могут показать инициализатор поля в декомпилированных результатах.

+3

Что делать, если конструктор типа присваивает другое значение? Тогда ваше значение по умолчанию бессмысленно. –

+0

Можете ли вы просто использовать (новый пример()). A, не так ли? – enkryptor

+2

Нет никакого разумного способа сделать это, не создавая экземпляр типа или не полагаясь на метаданные, такие как атрибут. – vcsjones

ответ

3

Вы можете получить значения констант, а не любые другие типы переменных, так как они должны иметь инициализированный класс для получения значения из, которое уже не является реальным значением по умолчанию, только текущее значение.

Ранее дубликат Get default value of class member сообщает, что делать, если вы отбрасываете не создавайте экземпляр ограничение.

Как насчет этого?

public class Example 
{ 
    public readonly DateTime a = DateTime.Now; 
} 

Не могли бы вы рассказать мне, что такое значение по умолчанию этого поля? Даже если бы вы могли, это не действительно значение по умолчанию, это оцененное значение определенной переменной в момент времени.

+3

По умолчанию в последнем примере используется '09/28/2015 16: 07: 08', no wait' 09/28/2015 16: 07: 20', no '09/28/2015 16: 07: 23. .. –

+0

Ты прибил его! @Jeppe –

1

Вы можете проверить код IL и искать членов, называемых .ctor (это конструкторы экземпляров).

Тогда найти один, который делает неcall другой Example::.ctor перегрузки, но вместо этого вызывает базовый конструктор класса, в вашем случае [mscorlib]System.Object::.ctor(). (Если не существует один, поле экземпляра Инициализаторы недостижим (патологический случай)!)

Затем внутри IL этот элемент, поле заданий stfld, которые приходят перед вызова базового класса .ctor, являются инициализаторами полей. Вуаля!

Смежные вопросы