5

可能重复:
您是否应该通过属性访问同一类中的变量?

我最近遇到了这个问题,我很好奇是否有某种标准,你应该在课堂上参考哪个标准。

我的意思是,无论您是直接访问成员变量还是通过属性(除非您需要避开一些自定义设置器代码),这都不应该有所不同,但我想确保没有最佳实践。

partial class MyClass {
    private string foo;

    internal string Foo {
        get {
            return foo;
        }

        private set {
            foo=value;
            // I do other stuff
        }
    }

    public void DoSomething() {
        //Option 1;
        Foo="some string";

        //Option 2;
        foo="some string";
    }
}
4

8 回答 8

3

这不应该是你真正做出的选择。setter 中的代码应该运行,在这种情况下使用属性,或者不应该运行,在这种情况下使用成员变量。在大多数情况下,一种是对的,一种是错的。在一般情况下,两者都不总是对/错,而且“无关紧要”是不寻常的。

例如,如果 setter 代码正在触发“已更改”事件,您是否希望通知外部对象它已更改?如果您要更改它以响应先前的更改,可能不会(无限递归任何人?)如果不是,您可能希望确保它被触发(这样您就不会更改值并且不会通知任何人更改)。

如果只是验证设置的值是否有效,那么您要么知道,在这种情况下,该值已经验证并且必须有效,在这种情况下无需再次验证;设置属性。如果您尚未验证要设置的内容,那么您希望验证逻辑运行,因此请使用该属性。

于 2013-01-23T18:03:59.453 回答
2

这个问题有很多争论,所以这个问题没有明显的答案。

就我个人而言,我更喜欢通过该属性进行访问,因为其中可能包含一些验证或转换代码。即使您的 getter 和 setter 微不足道,它们也可能在未来发生变化。

于 2013-01-23T17:54:52.233 回答
1

如果您将字段包装foo在 propertyFoo中,您可能是出于某种原因(转换、事件、验证等)这样做的。因此,一般来说,您应该引用该字段的唯一位置foo是在 property 的 getter 和 setter 中Foo。其余代码应引用该属性Foo

我确信存在一些模糊的情况,您需要绕过属性的 getter 和 setter,这当然可以,但这种情况将是规则的例外。

于 2013-01-23T18:01:50.000 回答
0

如果设置器没有逻辑,则显式声明私有变量没有意义,最好使用自动实现的属性:

    internal string Foo
    {
        get;
        private set;
    }

    public void DoSomething()
    {
        this.Foo = "some string";
    }

如果 setter 有逻辑,那么私有变量只能在 setter 中使用,绝不能在 setter 之外修改。在任何情况下(在我看来:))私有变量不应该出现在属性设置器旁边的任何其他地方。

于 2013-01-23T18:26:59.670 回答
0

我会选择选项 1。如果您要设置变量,则应该使用该属性而不是直接访问该变量。这是因为该属性具有您用“// 我做其他事情”指示的额外代码。您不希望仅仅因为您没有设置属性而重复这个“其他事情”......除非您不想在这次设置它时做“其他事情”。

老实说,这只是一个理论上的情况,如果你给出一个遇到这个问题的实际情况,答案会容易得多。

于 2013-01-23T17:59:39.080 回答
0

选项 1是很好的做法。因为如果你使用Option 2,你会在设置 foo 值时丢失其他东西。

于 2013-01-23T17:52:54.483 回答
0

想象一下这样的代码

public partial class HybridPanel: Panel {
    [DefaultValue(BorderStyle.FixedSingle)]
    public virtual new BorderStyle BorderStyle {
        set {
            if(value!=borderStyle) {
                borderStyle=value;
                base.PerformLayout();
            }
        }

        get {
            try {
                return borderStyle;
            }
            finally {
                if(borderStyle!=base.BorderStyle)
                    base.PerformLayout();
            }
        }
    }

    BorderStyle borderStyle=BorderStyle.FixedSingle;
    bool isCollapsed, isAutoSize;
}

在这种情况下,属性不仅用作变量,还可以做其他事情。访问同一类中的属性被认为是一种不好的做法,此外,编译器会建议:

仅用于访问字段而不传递参数的方法,请考虑将其定义为属性。

顺便说一句,您可以将访问成员变量目录的描述更正为直接访问成员变量(即使用字段访问)。

于 2013-01-23T18:31:53.440 回答
0

使用 INotifyPropertyChanged 接口时,如果您希望更新绑定对象,则必须使用属性。

于 2013-01-23T18:19:38.143 回答