.NET DefaultValue属性

我听说有人对DefaultValue属性做了一些不同的说明,包括:

  • “它在任何其他用途之前设定了财产的价值。”
  • “它不适用于自动function”。
  • “这只是装饰,你必须手动设置实际的默认值。”

哪个(如果有的话)是正确的? DefaultValue实际上是否设置了默认值? 有没有案件不起作用? 最好不要使用它?

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

来自MSDN:

一个DefaultValueAttribute不会导致一个成员被自动初始化为该属性的值。 您必须在代码中设置初始值。

MSDN – DefaultValueAttribute类


编辑:正如罗兰指出,和其他人在他们的答案中提到的属性也被使用的窗体devise器

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

MSDN继续说关于DefaultValueAttribute :

一个DefaultValueAttribute不会导致一个成员被自动初始化为该属性的值。 您必须在代码中设置初始值。

即你仍然需要使构造函数匹配你所说的默认值,这样信任它的代码仍然可以工作,比如内置的XML序列化将使用它们来确定是否序列化属性; 同样,表单devise人员将使用DefaultValue来确定需要自动生成的代码。

四年后更新:目前,设置JSON.net的DefaultValueHandling参数使得DefaultValue按照@aaron的预期工作:

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

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

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

“它在任何其他用途之前设定了财产的价值。” – >没有默认值是只为devise师。 默认值不会被seralized到devise器代码中。

“它不适用于自动function”。 – >没有

“这只是装饰,你必须手动设置实际的默认值。” – >否由于devise器序列化。 但是你必须手动设置。

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

你可以用Afterthought或Postharp这样的Aspect Orientated Frameworks来做这种魔术。