为了账号安全,请及时绑定邮箱和手机立即绑定

表达式主体属性和简单 Getter 属性之间的区别

表达式主体属性和简单 Getter 属性之间的区别

C#
UYOU 2023-07-22 15:38:35
在阅读了不同 c# 项目的一些源代码后,我注意到关于公共“getter”和私有“setter”属性的相同语句的不同编写方式(几乎)。第一种只有属性的方法:public int x { get; private set; }具有表达式主体属性的第二种方式:private int _x; public int x => _x;我知道这public int x { get; }相当于private readonly int __x; public int x { get { return __x } }所以我理解在单个“getter”的情况下表达式主体和普通属性之间的区别。我不明白的是当有一个私有字段保存引用值时的区别。我认为也许第二个更快,因为您可以直接访问该字段,而不是在类中调用方法。这只是一种风格上的差异,还是其中一个例子更快、更强大等等?
查看完整描述

3 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

您有两组等效的构造。


第 1 组


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


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 方法(对于每个自动属性,它也会注入一个支持字段)。在其他情况下,您可以直接访问该字段。注入的 setter 几乎肯定会被抖动内联,这消除了方法调用的性能损失。查看此问答以了解有关 JIT 内联的详细信息。


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


查看完整回答
反对 回复 2023-07-22
?
梦里花落0921

TA贡献1772条经验 获得超6个赞

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


public int X { get; }

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


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; } }。这也称为语法糖。



查看完整回答
反对 回复 2023-07-22
?
FFIVE

TA贡献1797条经验 获得超6个赞

如果您使用私有支持字段,您将封装信息并创建更健壮的代码。在某些情况下它还提高了可读性。
还有一个事实是,该值被安全地存储在一个字段中,因此,如果您的 getter 和 setter 中的逻辑需要在将来更改,那么它会与实际的值存储分离,并使将来更容易更改该实现

查看完整回答
反对 回复 2023-07-22
  • 3 回答
  • 0 关注
  • 159 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信