什么是不同之处...?[C#属性的GET/SET方式]

5

我知道在C#中,你可以轻松地创建访问器来访问数据类型,例如通过以下方式:

public class DCCProbeData
{
    public float _linearActual { get; set; }
    public float _rotaryActual { get; set; }
}

然而,我的同事建议我这样做:
public class DCCProbeData
{
    private float _linearActual = 0f;

    public float LinearActual
    {
        get { return _linearActual; }
        set { _linearActual = value; }
    }
    private float _rotaryActual = 0f;

    public float RotaryActual
    {
        get { return _rotaryActual; }
        set { _rotaryActual = value; }
    } 
}

我的方式似乎更简单、更简洁。这两种方法的区别和好处是什么?
谢谢。
编辑:请注意,我的同事能够使用在图表文件中最容易找到的类详细信息窗格中的“重构”选项生成“第二种方法”的代码。这使得添加许多属性变得容易,而不必手动创建访问器。

1
当你的同事给你建议时,他提到了哪些好处? - R. Martinho Fernandes
@Martinho 他提到了第一种方法使用匿名对象,但我不是很清楚他的意思。 @Alexei 谢谢,你是正确的,我应该像第二种方法那样使用属性的命名约定。 - Ryan R
@Ryan:从这些回答中可以看出,不存在“匿名对象”。当将短形式转换为长形式时,编译器会创建带有无法发音的名称的私有字段(也就是说,你不能使用它们的名称),所以可能这就是你的同事想要表达的意思。 - R. Martinho Fernandes
4
别忘记使用键盘上的“prop”并按下TAB TAB键 :-) - Ian
我相信这些关键词在某处都可以找到,可以去谷歌一下。我使用的其他一些关键词是'ctor'(构造函数)和'testm'(用于创建测试方法,在测试类中)-同样都需要按TAB TAB。我认为foreach也有一个关键词。你可以从Intellisense中看出哪些关键词可以构建这样的代码片段-例如,如果你在Intellisense列表中看到'prop',你会注意到它有一个与之相关联的奇怪形状的白色框形图标,ctor和testm也是如此,所以这可能是代码片段关键词的常见标志,据我所知。享受吧 :-) - Ian
显示剩余2条评论
13个回答

24

"Your way" 只是告诉编译器创建第二个选项。除非你在 getter 或 setter 中进行其他操作,否则它们在功能上是相同的。

然而,对于 "your way",我建议使用正确的 C# 命名约定。我个人会这样写:

public class DccProbeData
{
    public float LinearActual { get; set; }
    public float RotaryActual { get; set; }
}

1
为了完整性,你的同事的方法也允许设置属性的默认值。在你的代码上下文中,数字0f可能具有重要意义。 - T.K.
1
@Matt:如果该属性中没有任何内容,第二种表单在调试时有多少帮助?你会在那里调试什么? - R. Martinho Fernandes
1
@Martinho:你说得对,简单的访问器并不能给你太多东西,但我所指的是在getter和setter内部设置断点,以便您可以看到何时访问了内部成员以及其在不同时间的状态。我喜欢有一个成员,我可以将鼠标悬停在上面以查看其内部状态。如果内部成员以某种方式转换为属性,并且您想比较两者,这将变得特别有帮助。 - Matt Bishop
2
@Matt:好的,在某些情况下,断点可能很方便,但这种需要的频率并不会让我倾向于选择第二个。但这是个人/团队的偏好问题。但为什么依赖规范(关于默认值)是危险的做法呢? - R. Martinho Fernandes
4
@Matt:该规格保证了如果成员字段是整型,则将其初始化为零;如果它们是布尔值,则将其初始化为false;如果它们是引用类型,则将其初始化为null。当没有保证初始化时(例如未初始化的局部变量),编译器会拒绝编译。因此,是的,你可以依赖于“零”作为一个神奇的默认数值。您可以查阅规格的§12.2和§17.4.4节以获取详细信息。 - R. Martinho Fernandes
显示剩余12条评论

3
唯一的区别是您已经为字段命名了名称。
(我建议在公共属性方面使用您同事的命名约定。)

我不明白。你在说哪些公共字段? - R. Martinho Fernandes
抱歉 - 我的意思是公共属性 - 文本已更改。 - kͩeͣmͮpͥ ͩ

1

它们在内部执行相同的操作。唯一的区别是,您无法使用自动实现属性直接访问后备字段变量。


1

1

你的方法不允许你初始化值,而你同事的方法遵循更标准的命名约定。


1

我想补充一些其他答案中没有提到的内容,这使得第二种方法成为更好的选择:

使用第一种方法,您无法getset上设置断点。

使用第二种方法,您可以getset上设置断点,这对于调试访问您的私有变量的任何内容非常有帮助。


1

好的,这些名称之前已经提到过了。值得注意的是,除了不符合正常的.NET约定外,以下划线开头的公共名称也不符合CLS兼容性(实际上,使用它作为私有名称的原因之一就是因为这样可以使区分更清晰,并且如果您意外地拥有错误的访问级别,则应该在某些代码检查器中产生警告)。

除了名称之外,后一种形式的优点是可以添加更复杂的代码。但是,从前一种风格转换到后一种风格是不会破坏代码的,所以在需要之前没有理由这样做。


0

第一种方式适用于需要简单属性的情况,它会为您完成get和set以及私有存储。

如果您需要在获取或设置值时执行特殊操作,请使用第二种方式。

此外,我建议您遵循使用FxCop或ReSharper的命名约定。


0

我相信在IL级别上,它们最终都是一样的。在后台,当使用自动getter和setter时,VS会为您创建自动命名的变量。


0

唯一可能使这更好的方式是,如果您认为将来会向getter和setter添加更多逻辑。

即便如此,这似乎有点毫无意义。


1
如果你想添加更多的逻辑,它们仍然是一样的。 - R. Martinho Fernandes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接