C# 您应该在类中引用属性还是成员变量?

C# 您应该在类中引用属性还是成员变量?,c#,.net-4.0,properties,C#,.net 4.0,Properties,可能重复: 我最近遇到了这个问题,我很好奇,在一个类中,是否有某种你应该引用的标准 我的意思是,无论是直接访问成员变量还是遍历属性(除非您需要避开一些自定义setter代码),都不应该有什么区别,但我想确定的是,对于它没有最佳实践 partial class MyClass { private string foo; internal string Foo { get { return foo; } p

可能重复:

我最近遇到了这个问题,我很好奇,在一个类中,是否有某种你应该引用的标准

我的意思是,无论是直接访问成员变量还是遍历属性(除非您需要避开一些自定义setter代码),都不应该有什么区别,但我想确定的是,对于它没有最佳实践

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";
    }
}

选项1是良好的做法。因为如果使用选项2,在设置foo值时会丢失其他内容。

这个问题有很多争议,因此没有明显的答案


就个人而言,我更喜欢通过属性访问,因为其中可能包含一些验证或转换代码。尽管你的getter和setter都是微不足道的,但它们在将来可能会改变。

我会选择选项1。如果要设置变量,则应使用该属性,而不是直接访问该变量。这是因为属性具有您用“//I do other stuff”指示的额外代码。你不想因为没有设置属性就重复这个“其他东西”…除非,你这次设置时不想做“其他东西”


老实说,这只是一种理论上的情况,如果您给出遇到此问题的实际情况,回答起来会容易得多。

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


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

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

例如,如果setter代码正在触发一个“changed”事件,您是否希望外部对象收到它已更改的通知?如果您是为了响应之前的更改而更改它,可能不会(有人会无限递归吗?)如果没有,您可能希望确保它已被触发(这样您就不会更改值,也不会通知任何人更改)


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

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

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

    internal string Foo
    {
        get;
        private set;
    }

    public void DoSomething()
    {
        this.Foo = "some string";
    }
如果setter具有逻辑,则私有变量应仅在setter中使用,且不得在setter之外进行修改。 在任何情况下(在我看来:),私有变量都不应该出现在属性设置器旁边的任何地方

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;
}
在此上下文中,该属性不仅用作变量,还用作其他操作。 访问同一类中的属性是而不是被认为是不好的做法,此外,编译器建议:

一种仅用于访问字段而不传递参数的方法,而是将定义视为属性。


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

在某些情况下,使用该属性可能很关键(单例模式可能需要这样做),而在其他情况下,它可能完全不重要?如果您直接访问该成员,则
其他内容
不会完成。这是对的还是错的?除此之外,这是你/你的团队的决定。@O.R.Mapper-谢谢,显然我需要复习一下我的google fu,尝试过搜索,但找不到任何接近的东西。@Wrightboy:所以在侧边栏上显示另一个问题,作为“相关”部分的第一项。但我想在写这篇文章的时候也看不到。你能解释一下你所说的失去其他东西是什么意思吗?选项1属性访问器最好不要丢失其他内容。为什么选项2在这种情况下会更好?我的意思是那些代码不会运行。这很酷。我只是想看看你是否有不同的思路,是否有一些推理。你是对的,我使用了一个属性,因为无论何时访问foo,它都需要在返回之前对它做一些事情(验证/排序)。我通常是通过属性进行访问的,但是由于这种排序和类似的方法有点昂贵,在类内部,它被访问了很多次,因为根本不需要它。我不知道这样做是否会违反任何规则。我不确定我是否会在getter中放置一个昂贵的排序操作,但假设我会说这是绕过该属性的一个有效原因。我唯一会说绕过属性是完全错误的,如果它导致代码复制。是的,我只考虑制作一个方法GoSoReToFoE(),但是在类之外,我发现每次使用它都需要排序,所以我想为什么不只是排序。