繁体   English   中英

表达式绑定属性和简单Getter属性之间的区别

[英]Difference between Expression-Bodied Properties and simple Getter Properties

在阅读了不同c#项目的某些源代码之后,我注意到(几乎)关于公共“ getter”和私有“ setter”属性的不同书写方式(几乎)。

仅具有属性的第一种方式:

public int x { get; private set; }

具有表达主体属性的第二种方式:

private int _x;
public int x => _x;

我知道public int x { get; } public int x { get; }等同于

private readonly int __x;
public int x { get { return __x } }

因此,我了解在单个“ getter”的情况下表达式主体属性与正常属性之间的区别。 我不明白的是,当有一个私有字段保存引用的值时的区别。 我认为第二个可能更快,因为您可以直接访问该字段,而不是在类内部进行方法调用。 这仅仅是风格上的差异,还是示例之一更快,更强大等?

您有两组等效的构造。

第一组

当您不需要对构造函数外部的后备字段进行写访问时,可以使用以下任何一种结构:

private readonly int _x;
public int x => _x;

要么

private readonly int _x;
public int x { get => _x; }

要么

private readonly int _x;
public int x { get { return _x; } }

要么

public int x { get; }

2组

当需要访问构造函数外部的后备字段时,可以使用以下任何一种结构:

private int _x;
public int x => _x;

要么

private int _x;
public int x { get => _x; }

要么

private int _x;
public int x { get { return _x; } }

要么

public int x { get; private set; }

您可以期望所有替代方案的速度都一样快。 在最后一个构造中,编译器将注入一个setter方法(对于每个自动属性,它还将注入一个backer字段)。 在其他情况下,您可以直接访问该字段。 注入的setter几乎肯定会被抖动内联,这消除了方法调用的性能损失。 检查此问答以获取有关JIT内联的详细信息。

自动属性肯定更简洁,这使您的代码更加整洁,尤其是当您拥有许多属性时。 但归根结底,这取决于个人喜好(或您团队的编码规则)。

如果使用私有后备字段,则将封装信息并创建更可靠的代码。 在某些情况下,它还提高了可读性。
还有一个事实是,值安全地存储在字段中,因此,如果您的getter和setter方法中包含逻辑,将来需要更改,则它将与实际值存储区分开,从而使将来的实现更改更容易

请注意,如果您在构造函数中初始化属性,则还有另一种可能性

public int X { get; }

这是C#6.0中引入的仅吸气剂属性。 您可以在构造函数中分配它(然后不再分配)

public MyClass (int x) // Constructor
{
    X = x;
}

或使用初始化程序

public int X { get; } = 100;

您不应该关心这些事情的速度。 创建易于阅读且健壮的代码。 C#编译器或Jitter(在应用程序启动时运行的及时编译器,并且首次调用方法)可能会内联代码,甚至不会调用getter或setter。

正常属性和表示形式的属性,方法和构造函数之间的区别仅是语法性质。 行为没有差异。 两种变体产生相同的已编译IL代码,因此,速度没有差异。

public int X => _x; 只是public int X { get { return _x; } } public int X { get { return _x; } } 这也称为语法糖

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM