c# 6自动属性-读取一次或每次
本文关键字:一次 读取 属性 | 更新日期: 2023-09-27 18:08:23
在设置某些属性时,我遵循一种模式,即检查相应的字段是否为空,如果不是,则返回该字段,如果是,则设置该字段。例如,我经常使用它来读取配置设置,以便延迟读取设置,并且只读取一次。下面是一个例子:
private string DatabaseId
{
get
{
if (string.IsNullOrEmpty(databaseId))
{
databaseId = CloudConfigurationManager.GetSetting("database");
}
return databaseId;
}
}
我已经开始使用c# 6的自动属性初始化,因为它确实清理并使我的代码更简洁。我想这样做:
private string DatabaseId { get; } = CloudConfigurationManager.GetSetting("database");
但我不确定编译器如何解释它在这种情况下。这将有相同的效果,我的第一个代码块,设置(自动实现)字段一次,然后从字段读取?还是每次我得到DatabaseId
时它都叫CloudConfigurationManager
显示内容:
private string DatabaseId { get; } = CloudConfigurationManager.GetSetting("database");
是一个"自动属性初始化器",关键字是"初始化器",来自MSDN博客:c#:新的和改进的c# 6.0:
auto-property初始化器允许在属性声明中直接赋值。对于只读属性,它负责确保属性不可变所需的所有仪式。
初始化器每个实例运行一次(对于静态成员,每个类型运行一次)。参见c#语言规范,10.4.5变量初始化式:
对于实例字段,变量初始化式对应于类的实例创建时执行的赋值语句。
代码编译成这样:
public class ContainingClass
{
private readonly string _databaseId;
public string DatabaseId { get { return _databaseId; } }
public ContainingClass()
{
_databaseId = CloudConfigurationManager.GetSetting("database");
}
}
对于静态变量,这看起来是一样的:
private static string DatabaseId { get; } = CloudConfigurationManager.GetSetting("database");
大致编译为:
public class ContainingClass
{
private static readonly string _databaseId;
public static string DatabaseId { get { return _databaseId; } }
static ContainingClass()
{
_databaseId = CloudConfigurationManager.GetSetting("database");
}
}
c# 6.0 readonly auto property将创建一个字段并只调用一次初始化器。
然而,这并不等于你得到的。在您的代码中,CloudConfigurationManager.GetSetting
将仅在有人读取DatabaseId
属性时被调用,但是具有"只读自动属性"的CloudConfigurationManager.GetSetting
将在类初始化时被调用。
这个差异可能/可能无关紧要。视情况而定。如果调用是昂贵的,那么你可以使用Lazy<T>
,这大致等于你所拥有的。
它将只设置一次值,然后读取它。
然而,有一个轻微的区别,你现在不再有一个databaseId
字段。在第一个示例中,您基本上检查id == null || id == ""
以设置数据库字符串。这意味着,如果您创建一个新的实例,并将databaseId
设置为空字符串,那么第一个示例仍将从设置中获取ID。
然而,第二个例子将把空字符串视为有效值并保留它。
第一个代码:
if(id == null || id == "") // Get ID from settings
第二代码:if(id == null) // Get ID from settings
auto-property自动拥有一个后备字段。在这种情况下,该字段只能从构造函数或自动属性初始化器中赋值。你的新代码比第一个更好。它只会对CloudConfigurationManager.GetSetting("database");
进行一次调用。在第一个示例中,必须在每次调用属性get
时进行检查。