簡體   English   中英

.NET DefaultValue屬性

[英].NET DefaultValue attribute

我聽說過人們對DefaultValue屬性說了幾句不同的事情,包括:

  • “它在其他任何東西使用它之前設定了該屬性的價值。”
  • “它不適用於autoproperties。”
  • “它僅用於裝飾。您必須手動設置實際默認值。”

哪個(如果有的話)是對的? DefaultValue是否實際設置了默認值? 是否有不起作用的情況? 最好不要使用它嗎?

我通常使用DefaultValue的地方是用於序列化/反序列化為XML的類。 不會在實例化期間設置默認值,也不會影響autoproperties。

來自MSDN:

DefaultValueAttribute不會導致使用屬性的值自動初始化成員。 您必須在代碼中設置初始值。

MSDN - DefaultValueAttribute類


編輯:正如Roland指出的那樣,正如其他人在答案中提到的那樣,表單設計器也使用了該屬性

要在四年后更新:目前,設置JSON.net的DefaultValueHandling參數使DefaultValue按照@aaron預期的方式工作:

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

像所有屬性一樣,它是元數據,因此“它僅用於裝飾。您必須手動設置實際默認值。” 是最接近的。

MSDN繼續談到DefaultValueAttribute

DefaultValueAttribute不會導致使用屬性的值自動初始化成員。 您必須在代碼中設置初始值。

即,您仍然需要使構造函數與您所說的默認值匹配,以便信任它的代碼仍然有效,例如內置的XML序列化將使用它們來確定是否序列化屬性; 類似地,表單設計者將使用DefaultValue來計算出需要自動生成的代碼。

你實際上可以“強迫”它很容易在任何類上工作。

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

在最新版本的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;
}

“它在其他任何東西使用它之前設定了該屬性的價值。” - >不是默認值僅適用於設計人員。 默認值不會被分解為設計器代碼。

“它不適用於autoproperties。” - >不

“它僅用於裝飾。您必須手動設置實際默認值。” - >否。因為Designer序列化。 但您必須手動設置它。

來自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或Postsharp這樣的Aspect Orientated Frameworks來實現這種魔力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM