你如何给C#自动属性一个默认值?

你如何给C#自动属性一个默认值? 我要么使用构造函数,要么恢复到旧的语法。

使用构造函数:

class Person { public Person() { Name = "Default Name"; } public string Name { get; set; } } 

使用正常的属性语法 (使用默认值)

 private string name = "Default Name"; public string Name { get { return name; } set { name = value; } } 

有没有更好的办法?

在C#5及更早的版本中,为了赋予自动实现的属性默认值,你必须在构造函数中完成。

自C#6.0以来,包含自动属性初始值设定项的function已包含在内。 语法是:

 public int X { get; set; } = x; // C# 6 or higher 

编辑1/2/15

使用C#6,您可以直接初始化自动属性(最终!),现在在线程中还有其他解释这个问题的答案。

对于C#5及以下版本:

虽然该属性的预期用途不是实际设置属性的值,但可以使用reflection来始终设置它们。

 public class DefaultValuesTest { public DefaultValuesTest() { foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this)) { DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)]; if (myAttribute != null) { property.SetValue(this, myAttribute.Value); } } } public void DoTest() { var db = DefaultValueBool; var ds = DefaultValueString; var di = DefaultValueInt; } [System.ComponentModel.DefaultValue(true)] public bool DefaultValueBool { get; set; } [System.ComponentModel.DefaultValue("Good")] public string DefaultValueString { get; set; } [System.ComponentModel.DefaultValue(27)] public int DefaultValueInt { get; set; } } 

当你为一个variables内联一个初始值时,它将在构造函数中隐式地完成。

我会争辩说,这个语法是在C#中最好的做法5:

 class Person { public Person() { //do anything before variable assignment //assign initial values Name = "Default Name"; //do anything after variable assignment } public string Name { get; set; } } 

这样可以清楚地控制订单值的分配。

从C#6开始有一个新的方法:

 public string Name { get; set; } = "Default Name" 

DefaultValueAttribute只能在vsdevise器中工作。 它不会将该属性初始化为该值。

请参阅DefaultValue属性不与我的自动属性

有时我使用这个,如果我不希望它被实际设置,并坚持我的分贝:

 class Person { private string _name; public string Name { get { return string.IsNullOrEmpty(_name) ? "Default Name" : _name; } set { _name = value; } } } 

显然,如果它不是一个string,那么我可能会使对象为空(双?,int?),并检查它是否为空,返回一个默认值,或返回它设置的值。

然后,我可以在存储库中进行检查,看它是否是我的默认值,并且不会保留,或者在保存之前进行后门检查以查看备份值的真实状态。

希望有所帮助!

从C#6.0开始 ,我们可以将默认值分配给自动实现的属性。

 public string Name { get; set; } = "Some Name"; 

我们还可以创build只读自动实现的属性,如:

 public string Name { get; } = "Some Name"; 

请参阅: C#6:第一个反应,用于自动实现属性的初始化程序 – 作者:Jon Skeet

一点完整的样品:

 using System.ComponentModel; private bool bShowGroup ; [Description("Show the group table"), Category("Sea"),DefaultValue(true)] public bool ShowGroup { get { return bShowGroup; } set { bShowGroup = value; } } 

我的解决scheme是使用自定义属性,通过常量或使用属性types初始值设定项提供默认值属性初始化。

 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class InstanceAttribute : Attribute { public bool IsConstructorCall { get; private set; } public object[] Values { get; private set; } public InstanceAttribute() : this(true) { } public InstanceAttribute(object value) : this(false, value) { } public InstanceAttribute(bool isConstructorCall, params object[] values) { IsConstructorCall = isConstructorCall; Values = values ?? new object[0]; } } 

要使用这个属性,有必要从特定的基类初始化器inheritance一个类,或者使用一个静态辅助方法:

 public abstract class DefaultValueInitializer { protected DefaultValueInitializer() { InitializeDefaultValues(this); } public static void InitializeDefaultValues(object obj) { var props = from prop in obj.GetType().GetProperties() let attrs = prop.GetCustomAttributes(typeof(InstanceAttribute), false) where attrs.Any() select new { Property = prop, Attr = ((InstanceAttribute)attrs.First()) }; foreach (var pair in props) { object value = !pair.Attr.IsConstructorCall && pair.Attr.Values.Length > 0 ? pair.Attr.Values[0] : Activator.CreateInstance(pair.Property.PropertyType, pair.Attr.Values); pair.Property.SetValue(obj, value, null); } } } 

用法示例:

 public class Simple : DefaultValueInitializer { [Instance("StringValue")] public string StringValue { get; set; } [Instance] public List<string> Items { get; set; } [Instance(true, 3,4)] public Point Point { get; set; } } public static void Main(string[] args) { var obj = new Simple { Items = {"Item1"} }; Console.WriteLine(obj.Items[0]); Console.WriteLine(obj.Point); Console.WriteLine(obj.StringValue); } 

输出:

 Item1 (X=3,Y=4) StringValue 

在C#6及以上版本中,您可以简单地使用以下语法:

 public object Foo { get; set; } = bar; 

注意有一个readonly属性简单地省略集合,如下所示:

 public object Foo { get; } = bar; 

您也可以从构造函数中分配readonly自动属性。

在此之前,我回答如下。

我会避免添加一个默认的构造函数; 为dynamic赋值留下,并避免有两个点分配variables(即默认types和构造函数)。 通常我会在这种情况下写一个普通的属性。

另一个select是做ASP.Net所做的事情,并通过属性定义默认值:

http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

C#(6.0)及更高版本中 ,您可以执行以下操作:

Readonly属性

 public int ReadOnlyProp => 2; 

对于Writable和Readable属性

 public string PropTest { get; set; } = "test"; 

C#(7.0)的当前版本中,可以这样做:(代码片段显示了如何使用expression式get / set访问器在使用后备字段时更加紧凑)

 private string label = "Default Value"; // Expression-bodied get / set accessors. public string Label { get => label; set => this.label = value; } 

在C#6.0中,这是一件轻而易举的事!

你可以在Class声明本身的属性声明语句中做到这一点。

 public class Coordinate { public int X { get; set; } = 34; // get or set auto-property with initializer public int Y { get; } = 89; // read-only auto-property with initializer public int Z { get; } // read-only auto-property with no initializer // so it has to be initialized from constructor public Coordinate() // .ctor() { Z = 42; } } 

除了已经接受的答案之外,对于想要将默认属性定义为其他属性的函数的场景,您可以在C#6.0(及更高版本)上使用expression式正文expression式来获得更优雅和简洁的构造,如:

 public class Person{ public string FullName => $"{First} {Last}"; // expression body notation public string First { get; set; } = "First"; public string Last { get; set; } = "Last"; } 

您可以按照以下方式使用上述内容

  var p = new Person(); p.FullName; // First Last p.First = "Jon"; p.Last = "Snow"; p.FullName; // Jon Snow 

为了能够使用上面的“=>”表示法,该属性必须是只读的,并且不使用get访问器关键字。

有关MSDN的详细信息

 class Person { /// Gets/sets a value indicating whether auto /// save of review layer is enabled or not [System.ComponentModel.DefaultValue(true)] public bool AutoSaveReviewLayer { get; set; } } 
 public Class ClassName{ public int PropName{get;set;} public ClassName{ PropName=0; //Default Value } } 

在构造函数中。 构造函数的目的是初始化它的数据成员。

你有没有尝试使用DefaultValueAttribute或ShouldSerialize和Reset方法与构造函数? 如果你正在创build一个可能出现在devise器表面或属性网格中的类,我觉得这两个方法中的一个是必须的。

就个人而言,如果你不打算在汽车房地产之外做任何事情,我就没有把它变成房地产的意义。 只要把它作为一个领域。 这些物品的封装好处只是红鲱鱼,因为它们背后没有任何封装。 如果你需要改变底层的实现,你仍然可以自由的重构它们的属性,而不会破坏任何相关的代码。

嗯…也许这将是它后面自己的问题的主题

澄清,是的,你需要在类派生对象的构造函数中设置默认值。 您将需要确保构造函数存在与使用适当的访问修饰符的地方。 如果对象没有实例化,例如它没有构造函数(例如静态方法),那么默认值可以由字段设置。 这里的推理是对象本身只会被创build一次,而不会实例化它。

@Darren Kopp – 很好的答案,干净,正确。 重申一下,您可以为Abstract方法编写构造函数。 编写构造函数时只需要从基类访问它们:

基类的构造函数:

 public BaseClassAbstract() { this.PropertyName = "Default Name"; } 

Derived / Concrete / Sub-Class的构造函数:

 public SubClass() : base() { } 

这里的要点是,从基类中绘制的实例variables可能会掩埋您的基本字段名称。 使用“this”设置当前实例化的对象值。 将允许您针对当前实例正确地形成对象,并且在实例化它时需要权限级别(访问修饰符)。

使用构造函数是因为“构造函数完成时,施工完成”。 属性就像你的类所持有的状态,如果你必须初始化一个默认状态,你可以在你的构造函数中这样做。

我认为这会为你的游戏SomeFlag默认为false。

 private bool _SomeFlagSet = false; public bool SomeFlag { get { if (!_SomeFlagSet) SomeFlag = false; return SomeFlag; } set { if (!_SomeFlagSet) _SomeFlagSet = true; SomeFlag = value; } } 

初始化,使用构造函数初始化是不好的做法,并会导致更多的突破更改。

types道具和按下button“选项卡”和Visual Studiobuild议你下面的代码,

 public int MyProperty { get; set; } 

之后你可以更改修饰符,数据types,名称和轻松分配设置和获取值。

如果你需要在另一个类中使用一些variables

 public static int MyProperty { get; set; } 

在代码中你可以分配variables

 MyProperty=1; 

在另一个class级你可以使用这个,

 MessageBox.Show(Classname.MyProperty);