C#自动属性赋予初始值的最佳方式

C#自动属性赋予初始值的最佳方式

技术背景

在C#开发中,自动属性是一种方便的语法糖,它简化了属性的定义。然而,为自动属性赋予初始值在不同的C#版本中有不同的实现方式。了解这些方式有助于开发者根据项目的C#版本选择最合适的初始化方法。

实现步骤

C# 5及更早版本

在C# 5和更早的版本中,若要为自动实现的属性赋予初始值,需要在构造函数中完成。以下是示例代码:

1
2
3
4
5
6
7
8
9
class Person 
{
public Person()
{
// 分配初始值
Name = "Default Name";
}
public string Name { get; set; }
}

也可以使用反射结合DefaultValueAttribute来设置初始值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System.ComponentModel;
using System.ComponentModel;

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; }
}

C# 6.0及更高版本

从C# 6.0开始,可以直接在属性声明中指定初始值,语法如下:

1
public int X { get; set; } = x; // C# 6或更高版本

示例类:

1
2
3
4
5
6
7
8
9
10
public class Coordinate
{
public int X { get; set; } = 34; // 可读写自动属性并带有初始值
public int Y { get; } = 89; // 只读自动属性并带有初始值
public int Z { get; } // 只读自动属性,无初始值,需在构造函数中初始化
public Coordinate() // 构造函数
{
Z = 42;
}
}

还可以使用表达式体语法定义只读属性:

1
public int ReadOnlyProp => 2;

C# 9.0

C# 9.0增加了对init关键字的支持,这是一种非常有用且复杂的声明只读自动属性的方式:

1
2
3
4
5
6
7
8
9
10
11
class Person 
{
public string Name { get; init; } = "Anonymous user";
}
// 使用示例
var anonymous = new Person();
Console.WriteLine($"Hello, {anonymous.Name}!");
var me = new Person { Name = "@codez0mb1e"};
Console.WriteLine($"Hello, {me.Name}!");
// 以下代码会编译错误,因为init-only属性只能在对象初始化器中赋值
// me.Name = "My fake";

最佳实践

  • C# 6及更高版本:如果项目使用C# 6或更高版本,推荐直接在属性声明中指定初始值,这样代码更简洁。
  • 需要控制初始化顺序:如果需要明确控制属性的初始化顺序,建议在构造函数中进行初始化。
  • 只读属性:对于只读属性,可以使用表达式体语法或init关键字来定义。

常见问题

  • DefaultValueAttribute的作用DefaultValueAttribute主要用于VS设计器(或其他使用者)指定默认值,而不是初始值。在编译时,它不会影响生成的IL,也不会用于将属性初始化为该值。
  • 初始化顺序问题:如果在构造函数和属性声明中都进行了初始化,可能会导致初始化顺序混乱,应避免这种情况。

C#自动属性赋予初始值的最佳方式
https://119291.xyz/posts/2025-05-16.csharp-auto-property-initialization-best-way/
作者
ww
发布于
2025年5月16日
许可协议