【问题标题】:C# Automatic PropertiesC# 自动属性
【发布时间】:2009-08-18 15:32:10
【问题描述】:

我对 C# 中的自动属性有点困惑,例如

public string Forename{ get; set; }

我知道您通过不必声明私有变量来节省代码,但是当您不使用任何 get 或 set 逻辑时,属性的意义何在?为什么不直接使用

public string Forename; 

我不确定这 2 个语句之间的区别是什么,我一直认为如果你想要额外的 get/set 逻辑,你会使用属性?

【问题讨论】:

标签: c# c#-3.0 automatic-properties


【解决方案1】:

属性可以在不破坏契约的情况下将代码放入其中,字段不能在不将其更改为属性(并破坏接口)的情况下将代码放入其中。属性可以只读或只写,字段不能。属性可以是数据绑定的,字段不能。

【讨论】:

  • 您必须放置自己的支持字段。自动属性让您现在不必担心,但仍然为未来做好计划 - 请参阅我的答案了解详细信息。
  • @Gav,自动属性既简单又愚蠢。要添加逻辑,您必须将其转换为普通属性。 get 和 set 要么都是自动的,要么都不是。
  • +1 听过很多解释,这个解释最清楚了。
  • 好吧,只是为了确保我做对了,自动属性几乎是一个占位符,让您可以选择在某个时候删除它们并用属性替换它们?
  • 这也成为一个控制问题。通过让任何地方的任何代码设置字段,类模块无法控制并且无法知道字段可能具有的值。这会使错误更难发现,甚至会造成难以重现和发现错误。
【解决方案2】:

你可以写

public string Forename{ get; private set; }

获取只读属性...仍然不如真实属性通用,但对于某些作品来说这是一种折衷方案。

【讨论】:

    【解决方案3】:

    我不确定这两个语句之间的区别是什么,我一直认为如果你想要额外的 get/set 逻辑,你会使用属性?

    在第一种情况下,编译器会自动为你添加一个字段,并包装属性。基本上相当于做:

    private string forename;
    public string Forename
    {
        get
        { 
            return this.forename;
        }
        set
        {
            this.forename = value;
        }
    }
    

    使用属性而不是字段有很多优点。即使您不需要某些特定原因(例如数据绑定),这也有助于您的 API 经得起未来考验。

    主要问题是,如果您创建一个字段,但在您的应用程序的 v2 中需要一个属性,您将破坏 API。通过预先使用自动属性,您可以随时更改 API,无需担心源代码或二进制兼容性问题。

    【讨论】:

      【解决方案4】:

      这意味着您希望稍后添加逻辑。

      如果您这样做并从一开始就将其作为属性,您将不必重新构建依赖代码。如果您将其从变量更改为属性,那么您将不得不这样做。

      【讨论】:

      • 这是不正确的。这并不意味着您希望稍后添加逻辑。任何地方都没有这种推断的意图。它实际上只是使编写正确的代码(属性与字段)更容易的简写。
      【解决方案5】:
      【解决方案6】:

      公共数据成员是邪恶的(因为对象不控制对其自身状态的修改 - 它成为一个全局变量)。打破封装 - OOP 的原则。

      自动属性用于提供封装并避免为简单属性编写样板代码的繁琐工作。

      public string ID { get; set;}
      

      您将来可以将自动属性更改为非自动属性(例如,您在 setter 中进行了一些验证)...并且不会破坏现有客户端。

      string m_ID;
      public string ID
      {
         get { return m_ID; }
         set 
         { 
           //validate value conforms to a certain pattern via a regex match
           m_ID = value;
         }
      }
      

      您不能对公共数据属性做同样的事情。将数据属性更改为属性将强制现有客户端重新编译,然后才能再次交互。

      【讨论】:

      • 在某种程度上确实如此,但 OTOH 公共属性在封装方面并不比公共数据好多少:OOP 的原则是“告诉不问”,而使用属性(获取对象的内部状态)仍在询问而不是告诉。
      • 嗯...我要不同的是,IMO 公共属性比全局变量好得多。告诉不要问——我认为它是良好 OO 设计的启发式;当然也有例外,例如如果它是一个负责轮询 n 个设备并公开整体状态的类。它的工作是计算和传达最新状态 - 你必须“询问”,差异客户端可能会根据状态采取差异行动。 DAL 还需要询问方法。
      【解决方案7】:

      一方面,您可以将属性设置为虚拟并在继承类中实现逻辑。 之后你也可以在同一个类中实现逻辑,不会对依赖于类的任何代码产生副作用。

      【讨论】:

        【解决方案8】:

        在添加自动属性时,编译器会将 get set 逻辑添加到应用程序中,这意味着如果您稍后添加此逻辑,并且从外部库对您的属性的引用仍然有效。

        如果您从公共变量迁移到属性,这对于引用您的其他库来说将是一个重大更改 - 因此,为什么不从自动属性开始呢? :)

        【讨论】:

        • 优秀的答案。在您提出参考之前,我认为没有区别。
        【解决方案9】:

        并非所有属性都需要获取/设置逻辑。如果他们这样做,您将使用私有变量。 例如,在 MV-something 模式中,您的模型将没有太多逻辑。但你可以根据需要混合搭配。

        如果您要使用建议的字段代替属性,例如,您不能定义一个接口来正确描述您的类,因为接口不能包含数据字段。

        【讨论】:

          【解决方案10】:

          属性类似于合同,您可以更改属性的实现,而不会影响使用您的类和属性的客户端。您今天可能没有任何逻辑,但是随着业务需求的变化以及如果您想引入任何代码,属性是您最安全的选择。以下 2 个链接是优秀的 c# 视频教程。第一个视频解释了仅使用字段而不是属性的需要,第二个视频解释了不同类型的属性。我发现它们非常有用。

          Need for the Properties in C#

          Poperties in C#, Read Only, Write Only, Read/Write, Auto Implemented

          【讨论】:

            【解决方案11】:

            看看下面的代码和解释。
            The most common implementation for a property is getter or a setter that simply reads and writes to a private field of the same type as a property. An automatic property declaration instructs the compiler to provide this implementation. The compiler automatically generates a private backing field.
            查看以下代码:-

                public class Stock 
                {
                  decimal currentPrice ;  // private backing field.
                  public decimal CurrentPrice 
                  {
                    get { return currentPrice ; }
                    set { currentPrice = value ; }
                  }
               }
            

            同样的代码可以改写为:-

               public class Stock
               {
                 public decimal CurrentPrice { get ; set ; } // The compiler will auto generate a backing field.
               }
            

            来源:- 简而言之 C#

            【讨论】:

              猜你喜欢
              • 2010-10-09
              • 1970-01-01
              • 1970-01-01
              • 2011-08-12
              • 1970-01-01
              • 2014-08-22
              • 1970-01-01
              • 1970-01-01
              • 2012-02-15
              相关资源
              最近更新 更多