.NET DefaultValue属性

时间:2010-02-24 21:52:31

标签: c# .net properties attributes

我听说人们对DefaultValue属性说了几句不同的事情,包括:

  • “它在其他任何东西使用它之前设定了该属性的价值。”
  • “它不适用于autoproperties。”
  • “它仅用于装饰。您必须手动设置实际默认值。”

哪个(如果有的话)是对的? DefaultValue实际上是否设置了默认值?是否有不起作用的情况?最好不要使用它吗?

8 个答案:

答案 0 :(得分:49)

我通常使用DefaultValue的地方是用于序列化/反序列化为XML的类。 在实例化期间设置默认值,不会影响autoproperties。

来自MSDN:

  

DefaultValueAttribute不会导致使用属性的值自动初始化成员。您必须在代码中设置初始值。

MSDN - DefaultValueAttribute Class


编辑:正如Roland指出的那样,正如其他人在答案中提到的那样,表单设计器也使用了该属性

答案 1 :(得分:13)

要在四年后更新:目前,设置JSON.net的DefaultValueHandling参数使DefaultValue的工作方式与@aaron的预期相同:

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

答案 2 :(得分:12)

与所有属性一样,它是元数据,因此“它仅用于装饰。您必须手动设置实际默认值。”是最接近的。

MSDN继续说DefaultValueAttribute

  

DefaultValueAttribute不会导致使用属性的值自动初始化成员。您必须在代码中设置初始值。

即。您仍然需要使构造函数与您所说的默认值匹配,以便信任它的代码仍然有效,例如内置的XML序列化将使用它们来确定是否序列化属性;类似地,表单设计者将使用DefaultValue来计算出需要自动生成的代码。

答案 3 :(得分:8)

你实际上可以“强迫”它很容易在任何课程上工作。

首先,您需要在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();
    }

答案 4 :(得分:2)

“它在其他任何东西使用它之前设置属性的值。” - &GT;没有默认值仅适用于设计人员。默认值不会被分解为设计器代码。

“它不适用于autoproperties。” - &GT;否

“它仅用于装饰。您必须手动设置实际默认值。” - &GT;不,因为Designer Serialization。但是你必须手动设置它。

答案 5 :(得分:1)

来自MSDN帮助:

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>
        }

答案 6 :(得分:1)

在最新版本的C#中,您可以执行以下操作:

public class InitParam
{
    public const int MyInt_Default = 32;
    public const bool MyBool_Default = true;

    [DefaultValue(MyInt_Default)]
    public int MyInt{ get; set; } = MyInt_Default;

    [DefaultValue(MyBool_Default)]
    public bool MyBool{ get; set; } = MyBool_Default;
}

答案 7 :(得分:0)

你可以通过像Afterthought或Postsharp这样的面向方面的框架来实现这种魔力。