ben*_*ord 1773 c# automatic-properties
如何为C#Auto-Property提供默认值?我要么使用构造函数,要么还原为旧语法.
使用构造函数:
class Person
{
public Person()
{
Name = "Initial Name";
}
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用普通属性语法 (使用默认值)
private string name = "Initial Name";
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
Dar*_*opp 2140
在C#5和更早版本中,要为自动实现的属性提供默认值,您必须在构造函数中执行此操作.
自C#6.0起包含自动属性初始值设定项的功能.语法是:
public int X { get; set; } = x; // C# 6 or higher
Run Code Online (Sandbox Code Playgroud)
Chu*_*nce 287
编辑于1/2/15
C#6:
使用C#6,您可以直接初始化自动属性(最后!),现在线程中有其他答案可以描述.
C#5及以下:
虽然属性的预期用途不是实际设置属性的值,但您可以使用反射始终设置它们...
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; }
}
Run Code Online (Sandbox Code Playgroud)
Kei*_*ith 158
当你为变量内联一个初始值时,无论如何它都会隐式地在构造函数中完成.
我认为这种语法是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; }
}
Run Code Online (Sandbox Code Playgroud)
这样可以清楚地控制分配的订单值.
从C#6开始,有一种新的方式:
public string Name { get; set; } = "Default Name";
Run Code Online (Sandbox Code Playgroud)
cru*_*ble 59
有时我使用它,如果我不希望它实际设置并持久保存在我的数据库中:
class Person
{
private string _name;
public string Name
{
get
{
return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
}
set { _name = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
显然,如果它不是字符串,那么我可以使对象可以为空(double?,int?)并检查它是否为null,返回默认值,或返回它设置的值.
然后,我可以在我的存储库中检查它是否是我的默认值而不是持久存在,或者在保存之前检查后门以查看支持值的真实状态.
希望有所帮助!
Shi*_*iva 42
您可以在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;
}
}
Run Code Online (Sandbox Code Playgroud)
Hab*_*bib 39
从C#6.0开始,我们可以为自动实现的属性分配默认值.
public string Name { get; set; } = "Some Name";
Run Code Online (Sandbox Code Playgroud)
我们还可以创建只读的自动实现属性,如:
public string Name { get; } = "Some Name";
Run Code Online (Sandbox Code Playgroud)
请参阅:C#6:第一反应,自动实现属性的初始化程序 - 作者:Jon Skeet
ANe*_*own 29
在C#(6.0)及更高版本中,您可以执行以下操作:
对于Readonly属性
public int ReadOnlyProp => 2;
Run Code Online (Sandbox Code Playgroud)
对于可写和可读属性
public string PropTest { get; set; } = "test";
Run Code Online (Sandbox Code Playgroud)
在当前版本的C#(7.0)中,您可以执行以下操作:(在使用支持字段时,该代码段显示如何使用表达式的get/set访问器使其更紧凑)
private string label = "Default Value";
// Expression-bodied get / set accessors.
public string Label
{
get => label;
set => this.label = value;
}
Run Code Online (Sandbox Code Playgroud)
bra*_*roo 17
除了已经接受的答案之外,对于您希望将默认属性定义为其他属性的函数的场景,您可以在C#6.0(及更高版本)上使用表达式主体表示法,以获得更加优雅和简洁的结构,例如:
public class Person{
public string FullName => $"{First} {Last}"; // expression body notation
public string First { get; set; } = "First";
public string Last { get; set; } = "Last";
}
Run Code Online (Sandbox Code Playgroud)
您可以按以下方式使用上述内容
var p = new Person();
p.FullName; // First Last
p.First = "Jon";
p.Last = "Snow";
p.FullName; // Jon Snow
Run Code Online (Sandbox Code Playgroud)
为了能够使用上述"=>"表示法,该属性必须是只读的,并且不使用get accessor关键字.
有关MSDN的详细信息
ghi*_*boz 11
little complete sample:
using System.ComponentModel;
private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
get { return bShowGroup; }
set { bShowGroup = value; }
}
Run Code Online (Sandbox Code Playgroud)
int*_*ted 10
我的解决方案是使用自定义属性,该属性通过常量或使用属性类型初始化程序提供默认值属性初始化.
[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];
}
}
Run Code Online (Sandbox Code Playgroud)
要使用此属性,必须从特殊的基类初始化程序继承一个类或使用静态帮助程序方法:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
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);
}
Run Code Online (Sandbox Code Playgroud)
输出:
Item1
(X=3,Y=4)
StringValue
Run Code Online (Sandbox Code Playgroud)
在C#6及更高版本中,您只需使用以下语法:
public object Foo { get; set; } = bar;
Run Code Online (Sandbox Code Playgroud)
请注意,要使readonly属性只是省略该集合,如下所示:
public object Foo { get; } = bar;
Run Code Online (Sandbox Code Playgroud)
您还可以readonly从构造函数中指定自动属性.
在此之前,我回答如下.
我会避免在构造函数中添加默认值; 保留动态赋值,避免分配变量的两个点(即默认类型和构造函数).通常我只是在这种情况下写一个普通的属性.
另一个选择是执行ASP.Net所做的事情并通过属性定义默认值:
http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
在C# 9.0中添加了对init关键字的支持- 声明只读自动属性非常有用和复杂的方法:
宣布:
class Person
{
public string Name { get; init; } = "Anonymous user";
}
Run Code Online (Sandbox Code Playgroud)
~享受~使用:
// 1. Person with default name
var anonymous = new Person();
Console.WriteLine($"Hello, {anonymous.Name}!");
// > Hello, Anonymous user!
// 2. Person with assigned value
var me = new Person { Name = "@codez0mb1e"};
Console.WriteLine($"Hello, {me.Name}!");
// > Hello, @codez0mb1e!
// 3. Attempt to re-assignment Name
me.Name = "My fake";
// > Compilation error: Init-only property can only be assigned in an object initializer
Run Code Online (Sandbox Code Playgroud)
您是否尝试过将DefaultValueAttribute或ShouldSerialize 和 Reset 方法与构造函数结合使用?我觉得如果您要创建一个可能显示在设计器界面或属性网格中的类,则这两种方法之一是必要的。
private string name;
public string Name
{
get
{
if(name == null)
{
name = "Default Name";
}
return name;
}
set
{
name = value;
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样简单地放置
public sealed class Employee
{
public int Id { get; set; } = 101;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
781816 次 |
| 最近记录: |