代码之家  ›  专栏  ›  技术社区  ›  Aaron

.NET默认值属性

  •  45
  • Aaron  · 技术社区  · 16 年前

    我听说人们对 DefaultValue 属性包括:

    • “它在任何其他使用它之前设置属性的值。”
    • “它不适用于自动属性。”
    • “这只是为了装饰。必须手动设置实际默认值。“

    哪一个(如果有的话)是正确的?做 默认值 实际设置默认值?有没有不起作用的情况?最好不要用它吗?

    8 回复  |  直到 16 年前
        1
  •  47
  •   STW    16 年前

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

    来自MSDN:

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

    MSDN - DefaultValueAttribute Class


    编辑:正如罗兰指出的,正如他们答案中提到的,属性也被表单设计者使用。

        2
  •  12
  •   Rowland Shaw    16 年前

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

    微软继续说 DefaultValueAttribute :

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

    也就是说,您仍然需要使构造函数与您所说的默认值相匹配,以便信任它的代码仍然有效,例如内置的XML序列化将使用它们来计算是否对属性进行序列化;同样,表单设计器将使用 DefaultValue 计算出需要自动生成的代码。

        3
  •  12
  •   John Hatton    12 年前

    四年后更新:目前,设置json.net的 DefaultValueHandling 参数使默认值按@aron预期的方式工作:

    [JsonProperty("allowUploading",DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
    [DefaultValue(true)]
    public bool AllowUploading { get; set; }
    
        4
  •  8
  •   Thastograth    11 年前

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

    首先,需要在系统命名空间中写入对象扩展方法:

    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
  •  2
  •   gsharp    16 年前

    “它在任何其他使用它之前设置属性的值。” -->否。默认值仅适用于设计器。默认值将不会序列化到设计器代码中。

    “它不适用于自动属性。” ——没有

    “这只是为了装饰。必须手动设置实际默认值。“ -->否。因为设计器序列化。但必须手动设置。

        6
  •  1
  •   Ian Boyd    14 年前

    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>
            }
    
        7
  •  1
  •   Andrei Krasutski JohnnyQ    8 年前

    在最新版本的 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;
    }
    
        8
  •  0
  •   Thomas Haller    12 年前

    您可以使用面向方面的框架(如Afterthought或Postshap)来实现这种魔力。

    推荐文章