Подтвердить что ты не робот

Атрибут .NET DefaultValue

Я слышал, что люди говорят несколько разных вещей об атрибуте DefaultValue, включая:

  • "Он устанавливает значение свойства прежде, чем что-либо еще его использует".
  • "Это не работает для autoproperties".
  • "Это только для украшения. Вы должны вручную установить фактические значения по умолчанию".

Какой (если есть) правильный? Действительно ли DefaultValue устанавливает значения по умолчанию? Существуют ли случаи, когда они не работают? Лучше всего не использовать его?

4b9b3361

Ответ 1

Место, где я обычно использовал DefaultValue, для классов, которые сериализуются/десериализуются в XML. Он не устанавливает значение по умолчанию во время создания экземпляра и не влияет на автопроцессы.

Из MSDN:

A DefaultValueAttribute не приведет к тому, что элемент будет автоматически инициализирован значением атрибута. Вы должны установить начальное значение в своем коде.

MSDN - класс DefaultValueAttribute


Изменить: как указывает Роланд, и, как упоминалось в других ответах, атрибут также используется конструктором форм

Ответ 2

Как и все атрибуты, это метаданные, и как таковые "Это только для украшения. Вы должны вручную установить фактические значения по умолчанию". ближе всего.

В MSDN говорится о DefaultValueAttribute:

A DefaultValueAttribute не приведет к тому, что элемент будет автоматически инициализирован значением атрибута. Вы должны установить начальное значение в своем коде.

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

Ответ 3

Чтобы обновить это четыре года спустя: установка параметра JSON.net DefaultValueHandling делает DefaultValue таким, как ожидалось: aaaron:

[JsonProperty("allowUploading",DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
[DefaultValue(true)]
public bool AllowUploading { get; set; }

Ответ 4

Вы действительно можете "заставить" его работать в любом классе довольно легко.

Сначала вам нужно написать метод расширения объекта в пространстве имен System:

public static class ObjectExtensions
{
    public static void InitializePropertyDefaultValues(this object obj)
    {
        PropertyInfo[] props = obj.GetType().GetProperties();
        foreach (PropertyInfo prop in props)
        {
            var d = prop.GetCustomAttribute<DefaultValueAttribute>();
            if (d != null)
                prop.SetValue(obj, d.Value);
        }
    }
}

Затем в конструкторе класса, который достаточно высок в иерархии ваших классов, которые действительно нуждаются в такой автоматической инициализации по умолчанию, вам просто нужно добавить одну строку:

    public MotherOfMyClasses()
    {
        this.InitializePropertyDefaultValues();
    }

Ответ 5

"Он устанавливает значение свойства прежде, чем что-либо еще его использует." - > Нет значения по умолчанию для дизайнера. значение по умолчанию не будет серализоваться в коде конструктора.

"Это не работает для autoproperties". - > Нет

"Это только для украшения. Вы должны вручную установить фактические значения по умолчанию". - > Нет. Из-за сериализации конструктора. Но вы должны установить его вручную.

Ответ 6

Из MSDN help:

AttributeCollection^ attributes = TypeDescriptor::GetProperties( this )[ "MyProperty" ]->Attributes;

/* Prints the default value by retrieving the DefaultValueAttribute 
      * from the AttributeCollection. */
DefaultValueAttribute^ myAttribute = dynamic_cast<DefaultValueAttribute^>(attributes[ DefaultValueAttribute::typeid ]);
Console::WriteLine( "The default value is: {0}", myAttribute->Value );

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


Решено путем переопределения функций ShouldSerialize в классе, содержащем свойства.

Пример:

property System::String^ Z {
            System::String^ get(){...}
            void set(System::String^ value) {...}
        }

        bool ShouldSerializeZ() {
            return Z != <call to run time objects>
        }

Ответ 7

вы можете сделать такую ​​магию с помощью Ориентированных на Ориентацию рамок, таких как Afterthought или Postsharp.