Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 了解自动实现的属性_C#_.net 3.5_Properties_Automatic Properties - Fatal编程技术网

C# 了解自动实现的属性

C# 了解自动实现的属性,c#,.net-3.5,properties,automatic-properties,C#,.net 3.5,Properties,Automatic Properties,我有一个使用自动实现属性的简单类: Public Class foo { public foo() { } public string BarName {get; set;} } 显然,我在整个类中都使用了变量BarName,现在需要在设置属性值时添加逻辑(必须是大写的,如图所示)。这是否意味着我现在需要为BarName创建一个私有变量,例如_BarName,并将整个类中使用的当前BarName变量更改为_BarName Public Class foo { pu

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

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时,我需要调用一些方法;然后更改值


这似乎是对设置属性的一行又一行代码的公平权衡

你不需要改变任何事情。自动实现的属性只是语法糖。编译器正在幕后为您生成私有变量和get/set逻辑。如果您添加自己的getter/setter逻辑,编译器将使用您的代码而不是自动生成的代码,但是对于该属性的用户来说,没有任何更改;任何引用您的属性的代码都将继续工作。

您对重构的看法是正确的,它真的不应该破坏任何东西

您是否确实需要遍历类中对属性名称的引用,并更改这些引用以引用私有字段,这取决于内部代码是否需要访问数据的底层表示,而不是如何将数据呈现给类的使用者。在大多数情况下,你可以不去管它

在您的简单示例中,明智的做法是充分考虑并确保类内部的任何代码都不会破坏setter中正在执行的转换/格式设置

另一方面,如果getter正在做一些魔术,将字段的内部表示更改为使用者查看数据所需的方式,那么(在某些情况下)类中的内部代码可能需要访问字段


您需要查看类中每次出现的对auto属性的访问,并决定它是应该接触字段还是使用属性。

使用自动属性时,您无法直接访问底层的“backing”变量,则无法访问在属性getter和setter中实现的实际逻辑。您只能访问该属性(因此在整个代码中使用BarName)

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


在您的示例中,您认为这不是一个突破性的更改是正确的。这种类型的重构(从自动属性移动到“正常”属性永远不应该是突破性的更改,因为您没有更改公共接口(公共属性的名称或可访问性).

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

稍后,如果您想要为属性实现getter和setter,那么您只需要为它创建一个显式的私有成员并添加逻辑

这是否意味着我现在需要 为BarName创建一个私有变量

并更改当前的名称 在我的课堂上使用的变量

不要更改类中的其余代码以使用您创建的新私有变量。BarName作为属性,旨在隐藏私有变量(除其他外),以避免对代码的其余部分进行全面更改

我假设重构 如上所示,这不是一个突破性的变化 因为物业基本上是 保持不变;只是花了一点时间 没有什么工作可以让它保持这样 添加所需的逻辑


正确。

如果您知道要验证该对象,请不要使用自动属性。这些对象可以是域对象等。例如,如果您有一个Customer类,则使用私有变量,因为您可能需要验证名称、生日等。但是如果您使用的是Rss类,则可以只使用自动pr属性,因为没有执行验证,类只是用来保存一些数据。

好的。但是为了向setter和getter引入逻辑,我需要像我在示例中所做的那样更改代码,对吗?是的,它可以正常工作。调用ToString()在一个字符串上有点多余,但它不会伤害任何东西。如果我需要在调用getter或setter时调用某个方法呢?Brettski:我不确定我是否理解…你可以从属性的getter/setter调用一个方法,就像从任何其他方法一样。get{…}和set{…}构造本身就是语法糖:编译器生成getFoo()和setFoo()方法。啊,所以我自己使用属性来访问变量?如果它是只读的,我就不能这样做。我的意思是需要更改的代码是/inside/classIn在您的示例中,它不是只读的。但是,现在您提出了它,我的回答是,您可以使该属性公开可读并私下设置