【问题标题】:What is the difference...? [C# properties GET/SET ways]有什么不同...? [C# 属性 GET/SET 方式]
【发布时间】:2011-03-24 16:22:01
【问题描述】:

我知道在 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; }
    } 
}

我的方式似乎更简单,更简洁。这两种方法有什么区别和好处?

谢谢

编辑 请注意,我的同事能够使用“类详细信息”窗格中的“重构”选项生成“第二种方式”的代码,该选项最容易在图表文件中找到。这样可以轻松添加许多属性,而无需手动创建访问器。

【问题讨论】:

  • 您的同事在为您提供建议时提到了哪些好处?
  • 我认为解释是“你的命名看起来很像你公开暴露内部变量。如果你想保留下划线版本供内部使用 - 将它们设为私有并提供具有良好名称的公共属性_ 字段。”
  • @Martinho 他提到了第一个使用匿名对象的事情,但我不太清楚他的意思。 @Alexei谢谢,你是对的,我应该像第二种方式一样使用属性的命名约定。
  • @Ryan:从这里的答案可以看出,没有“匿名对象”。在将短格式转换为长格式时,编译器会创建带有 无法发音的名称 的私有字段(也就是说,您无法使用它们的名称),所以也许这就是您同事的意思。
  • 不要忘记使用 'prop' 然后在键盘上使用 TAB TAB :-)

标签: c# syntax properties field


【解决方案1】:

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

但是,对于“你的方式”,我建议使用正确的 C# 命名约定。我个人会这样写:

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

【讨论】:

  • 为了完整起见,您同事的方式还允许设置属性的默认值。在您的代码上下文中,数字 0f 可能对某些事情很重要。
  • @Matt:第二种形式在调试时有多大帮助,如果该属性中没有发生任何事情?你会在那里调试什么?
  • @Martinho :你是对的,简单的访问器不会给你太多,但我指的是在 getter 和 setter 中放置断点,这样你就可以看到你的内部成员何时被hit 以及它在不同时间的状态。我喜欢有一个可以悬停在上面查看其内部状态的成员。如果内部成员以某种方式转换为属性并且您想比较两者,这将变得特别有用。
  • @Matt:好的,断点在某些情况下可能会派上用场,但这种需求的频率不会促使我更喜欢第二个。但无论如何,这是个人/团队的偏好。但是为什么依赖规范(关于默认值)是一种危险的做法?
  • @Matt:规范保证成员字段如果是整数类型则初始化为零,如果它们是布尔类型则初始化为 false,如果它们是引用类型则初始化为 null .当没有保证初始化(如未初始化的局部变量)时,编译器拒绝编译。所以,是的,零是您可以依赖的神奇默认数字。有关详细信息,您可以查阅规范的 §12.2 和 §17.4.4 部分。
【解决方案2】:

唯一的区别是您已经命名了这些字段。

(不过,我会坚持你的同事对公共属性的命名约定。)

【讨论】:

  • 我不明白。你在说什么公共领域?
  • 抱歉 - 是指公共属性 - 文本已更改
【解决方案3】:

他们在内部做同样的事情。唯一的区别是您不能使用自动实现的属性直接访问支持字段变量。

【讨论】:

    【解决方案4】:

    它们在技术上是相同的...... get/set 是简写 (auto property)。

    关于这个的很多问题:

    1. When to use get; set; in c#
    2. What is the { get; set; } syntax in C#?
    3. Auto-Implemented Properties c#

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我想添加一些我在其他答案中没有看到的东西,这使得 #2 成为更好的选择:

        使用第一种方法不能getset 上设置断点。

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

        【讨论】:

          【解决方案7】:

          好的,前面已经提到过这些名字。还值得注意的是,除了不符合正常的 .NET 约定外,以下划线开头的公共名称不符合 CLS(实际上,将其用于私有名称的一个原因正是因为这一点,它做出了区分更清晰,如果您不小心使用了错误的访问级别,应该会导致一些代码检查器发出警告)。

          除了名称,后一种形式的一个优点是您可以添加更复杂的代码。尽管如此,从前一种风格转变为后一种风格是一种非破坏性的改变,所以没有理由在需要之前就这样做。

          【讨论】:

            【解决方案8】:

            当您需要简单的属性并为您完成获取和设置以及私有存储时,第一种方法是可行的。

            如果在获取或设置值时需要做一些特殊的事情,请使用第二种方式。

            另外,我建议您坚持使用 FxCop 或 ReSharper 的命名约定。

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                【解决方案10】:

                这可能会更好的唯一方法是,如果您觉得以后会在 getter 和 setter 中添加更多逻辑。

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

                【讨论】:

                • 如果你想添加更多的逻辑,它们还是一样的。
                【解决方案11】:

                在您的代码示例将自动生成支持字段的意义上,它们是相同的。

                但是两个代码示例是不同的,因为属性的名称不一样(LinearActual vs linearActual

                【讨论】:

                  【解决方案12】:

                  没有区别,但是在 C# 3 之前,您必须使用 long way。归根结底,它是一个 C# 功能 - 语法糖。它们在功能上是相同的。

                  【讨论】:

                  • 语法糖!嘿,我喜欢这样!
                  • @Ryan R - 哈哈我不太清楚我是从哪里听到的,我确定是微软的一些文献
                  • @Ryan @m.edmondson:syntactic sugar 上有一个维基百科页面。
                  【解决方案13】:

                  不使用自动实现属性时可以做的事情:

                  • 初始化为默认值
                  • 访问或注释支持字段(属性)
                  • 只读支持字段或不变性
                  • 在访问时设置断点
                  • 具有访问变量的自定义代码
                  • 使用[System.ComponentModel.EditorBrowsableAttribute()] 在访问器上启用自定义逻辑,以避免在编码时意外绕过
                    • 对智能感知隐藏支持字段

                  使用 ReSharper,这两种方式之间的转换非常简单。

                  这并不是说不要使用它们,除非您需要列出的任何其他功能。

                  【讨论】:

                    猜你喜欢
                    • 2018-04-03
                    • 2015-08-19
                    • 1970-01-01
                    • 2011-10-03
                    • 2011-04-14
                    • 1970-01-01
                    • 2019-05-09
                    • 2011-03-14
                    • 2010-11-23
                    相关资源
                    最近更新 更多