C# .NET 默认值属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2329868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:28:51  来源:igfitidea点击:

.NET DefaultValue attribute

c#.netpropertiesattributes

提问by Aaron

I've heard people say a few different things about the DefaultValueattribute including:

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

  • "It sets the value of the property before anything else uses it."
  • "It doesn't work for autoproperties."
  • "It's only for decoration. You must manually set actual default values."
  • “它在其他任何东西使用它之前设置了财产的价值。”
  • “它不适用于自动属性。”
  • “仅用于装饰。您必须手动设置实际默认值。”

Which (if any) is right? Does DefaultValueactually set default values? Are there cases where it doesn't work? Is it best just not to use it?

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

采纳答案by STW

The place where I typically used DefaultValueis for classes which are serialized/deserialized to XML. It does notset the default value during instantiation and doesn't impact autoproperties.

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

From MSDN:

来自 MSDN:

A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.

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

MSDN - DefaultValueAttribute Class

MSDN - DefaultValueAttribute 类



Edit: As Roland points out, and as others mentioned in their answers the attribute is also used by the Form Designer

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

回答by gsharp

"It sets the value of the property before anything else uses it." --> No the default value is only for the designer. a default value will not be seralized into the designer code.

“它在其他任何东西使用它之前设置了财产的价值。” --> 否 默认值仅适用于设计器。默认值不会被序列化到设计器代码中。

"It doesn't work for autoproperties." --> No

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

"It's only for decoration. You must manually set actual default values." --> No. Because of the Designer Serialization. But you must set it manually.

“仅用于装饰。您必须手动设置实际默认值。” --> 没有。因为Designer Serialization。但是您必须手动设置它。

回答by Rowland Shaw

Like all attributes, it's meta data, and as such "It's only for decoration. You must manually set actual default values." is closest.

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

MSDN goes on to say about DefaultValueAttribute:

MSDN 继续介绍DefaultValueAttribute

A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.

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

i.e. You still need to make the constructor match what you say is the default value so that code that trusts it still works, such as the built in XML Serialization will use them to work out whether to serialise the property or not; similarly the form designer will use the DefaultValues to work out what code needs to be automatically generated.

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

回答by Adam

From MSDNhelp:

来自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 );

I need to set the default value attribute to something non static. How can I basically set it whenever I want to?

我需要将默认值属性设置为非静态的。我如何基本上可以随时设置它?



Solved by overriding the ShouldSerialize functions in the class holding the properties.

通过覆盖保存属性的类中的 ShouldSerialize 函数来解决。

Example:

例子:

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

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

回答by Thomas Haller

you can make this kind of magic happen with Aspect Orientated Frameworks like Afterthought or Postsharp.

您可以使用 Afterthought 或 Postsharp 等面向方面的框架实现这种魔法。

回答by John Hatton

To update this four years later: Currently, setting JSON.net's DefaultValueHandlingparameter makes DefaultValue work the way @aaron expected:

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

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

回答by Thastograth

You actually can "force" it to work on any class pretty easily.

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

First you need to write object extension method in the System namespace:

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

Then in the constructor of a class which is high enough in the hierarchy of your classes that actually need such auto default value initialization you just need to add one line:

然后在类的层次结构中足够高的类的构造函数中,实际上需要这种自动默认值初始化,您只需要添加一行:

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

回答by Andrei Krasutski

In the latest versions of C#, you can do:

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