了解自动实现的属性

时间:2020-03-06 15:03:38  来源:igfitidea点击:

我有使用自动实现的属性的简单类:

Public Class foo
{
    public foo() { }  

    public string BarName {get; set;}
}

我显然在整个类中都使用了BarName变量,现在在设置属性值时需要添加逻辑(必须全部为大写,如图)。这是否意味着我现在需要为BarName创建一个私有变量,例如_BarName,并将在我的课程中使用的当前BarName变量更改为_BarName?

Public Class foo
{
    public foo() {}  

    private string _BarName = "";
    public string BarName 
    { 
        get {return _BarName;}
        set {_BarName = Value.ToString().ToUpper();}
    }
}

我试图确保我了解使用自动实现的属性的含义,以及当/如果我需要更改某些内容,它将带来什么。我假设如上所述的重构并不是一个重大更改,因为该属性基本上保持不变。只需要在类中进行一些工作即可保持这种状态并添加所需的逻辑。

另一个示例可能更有意义,那就是在使用setter或者getter时,我需要调用某种方法。然后再更改值。

在设置属性的代码行和代码行之间,这似乎是一种公平的交易。

解决方案

我们无需更改任何内容。自动实现的属性只是语法糖。编译器在后台为我们生成私有变量和获取/设置逻辑。如果添加自己的getter / setter逻辑,则编译器将使用代码而不是其自动生成的代码,但是就该属性的用户而言,什么都没有改变;任何引用媒体资源的代码将继续起作用。

我们对重构是正确的,它实际上不应破坏任何东西。

是否实际上需要遍历类内对属性名称的引用,并将其更改为引用私有字段,将取决于是否需要内部代码访问数据的基础表示形式,而不是如何将其呈现给消费者的阶级。在大多数情况下,我们可以保持足够的孤独。

在简单示例中,明智的做法是保持足够的独立性,并确保该类内部的任何代码都不能破坏在setter中执行的转换/格式设置。

另一方面,如果吸气剂正在做某种魔术来将字段的内部表示形式更改为消费者查看数据所需的方式,则(在某些情况下)类中的内部代码可能需要访问字段。

我们将需要查看该类中对自动属性的每次访问,并确定是应该接触该字段还是使用该属性。

使用自动属性时,我们无法直接访问基础的"后备"变量,也无法访问在属性getter和setter中实现的实际逻辑。我们只能访问该属性(因此在整个代码中都使用BarName)。

如果现在需要在设置器中实现特定的逻辑,则不再可以使用自动属性,而需要以"老式"方式实现该属性。在这种情况下,我们将需要实现自己的私有支持变量(至少对我来说,首选方法是将私有支持变量命名为与属性相同的名称,但以小写字母开头(在这种情况下,变量将被命名为barName),然后我们将在getter / setter中实现适当的逻辑。

在示例中,我们认为这不是一个重大更改是正确的。这种类型的重构(从自动属性更改为"常规"属性永远不会是一项重大更改,因为我们没有更改公共接口(公共属性的名称或者可访问性)。

自动属性只是语法糖,实际上编译器会为其创建私有成员,但是由于它是在编译时生成的,因此我们无法访问它。

然后,如果要为属性实现getter和setter,则只有为它创建一个显式的私有成员并添加逻辑。

Does this mean that I need to now
  create a private variable for BarName

是的

and change the current BarName
  variable used throughout my class

不要将类中的其余代码更改为使用我们创建的新私有变量。 BarName作为属性,旨在隐藏私有变量(除其他外),目的是避免我们打算对代码其余部分进行大范围更改。

I am assuming that the refactoring, as
  shown above, is not a breaking change
  because the property is basically
  staying the same; it just took a
  little work to keep it that way and
  add the needed logic.

正确的。

如果我们知道要验证该对象,请不要使用自动属性。这些对象可以是域对象等。例如,如果我们有一个Customer类,则可以使用私有变量,因为我们可能需要验证名称,生日等。但是,如果我们使用的是Rss类,那么可以使用自动属性就可以了。因为没有执行验证,并且该类仅用于保存一些数据。