你如何给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);