我应该使用公共属性和私有字段或公共字段来获取数据吗?

时间:2009-08-14 12:26:31

标签: c# .net coding-style properties

在我看过的大部分代码中(在SO上,我都会在我自己的代码中使用codeproject.com),我已经看到为类包含的每个私有字段创建了公共属性,即使它们是是get; set;最基本的类型:

private int myInt;
public int MyInt 
{
     get { return myInt; }
     set { myInt = value }
}

我的问题是:这与以下方面有何不同:

public int MyInt;

如果我们应该使用属性而不是公共字段,为什么我们应该在这种特定情况下使用它们呢? (我不是在谈论更复杂的例子,其中getter和setter实际上做了一些特殊的事情,或者只有一个get或set(只读/写)而不仅仅是返回/设置私有字段的值)。它似乎没有添加任何额外的封装,只在IntelliSense中提供一个漂亮的图标,并放在类图中的特殊部分!

13 个答案:

答案 0 :(得分:33)

请参阅此文http://blog.codinghorror.com/properties-vs-public-variables/

特别是

  • 反射在变量与属性上的工作方式不同,因此如果依赖于反射,则更容易使用所有属性。
  • 您无法对变量进行数据绑定。
  • 将变量更改为属性是一个重大变化。

答案 1 :(得分:21)

三个原因:

  1. 您不能像子属一样覆盖子类中的字段。
  2. 您最终可能需要更复杂的getter或setter,但如果它是一个字段,更改它会破坏API。
  3. 公约。这就是它的完成方式。
  4. 我确信我有更多的理由不在考虑。

    在.Net 3.x中,您可以使用以下自动属性:

    public int Age { get; set; }
    

    而不是旧学校的方式,自己就像这样宣布你的私人领域:

    private int age;
    
    public int Age
    {
        get { return age; }
        set { age = value; }
    }
    

    这使得它像创建一个字段一样简单,但没有突破性变化问题(除其他外)。

答案 2 :(得分:8)

创建私有字段名称时,以及实际获取并设置名称字段值的简单公共属性名称

public string Name
{
   get { return name; }
}

并且您在课堂外的任何地方都使用此属性,有一天您决定此类的名称属性实际上会引用 lastName 字段(或您想要的)要返回一个字符串“我的名字:”+名称),你只需更改属性中的代码:

public string Name
{
   get { return lastName; //return "My name: "+name; }
}

如果您在外部代码中的任何位置使用公共字段名称,那么您必须在使用它的任何地方将名称更改为 lastName

答案 3 :(得分:5)

它确实有所作为。可以在对象实例不知道的情况下更改公共数据。使用getter和setter,对象始终知道已经进行了更改。

请记住,封装数据只是迈向更好的结构化设计的第一步,它本身并不是最终目标。

答案 4 :(得分:4)

在以下情况下,您必须使用属性:

  1. 当您需要将属性中的数据序列化为某种格式时。
  2. 当您需要覆盖派生类中的属性时。
  3. 使用某些逻辑实现get和set方法时。例如,当您实现Singleton模式时。
  4. 当您从接口派生时,声明了属性。
  5. 当您遇到与反射相关的特定问题时。

答案 5 :(得分:2)

它......取决于?

我总是使用getter& setters,因为他们创建了这个快捷方式:

public int Foo {get;组; }

在编译时它被翻译。现在你无法想象它,但它就在那里,如果你需要得到想象,你只需稍后拼出来。

然而,公共,私人,受保护......这都是您希望能够调整数据的问题。我们经常使用继承,这对我们来说是一种非常常见的方法,所以只有孩子才能编辑某些属性。

protected _foo;  
public Foo  
{  
    get { return _foo; }
} //lack of set intentional.

答案 6 :(得分:0)

原因有很多。

主要是:

  • 设置变量
  • 时,您可以执行其他一些功能
  • 您可以阻止设置并仅提供
  • 某些“事物”仅适用于属性(例如,DataBinding)
  • 您可以隐藏属性的实现[也许它是ASP.NET中的ViewState变量。)。

答案 7 :(得分:0)

关键是 - 如果你想要确保每次myInt被引用时发生特殊情况(写入日志文件,将其更改为42等),那该怎么办呢?没有吸气剂和制定者,你不能这样做。有时候为你可能需要的东西编程是明智的,而不是你现在需要的东西。

答案 8 :(得分:0)

实际上,如果您正在使用Silverlight,您将意识到无法将字段设置为静态资源,因此您必须使用属性(甚至访问const)。

我意识到当我尝试联合我在复合指导(PRISM)中使用的区域名称时。

然而,这只是一种语言限制,除static / const字段外,我总是使用属性。

答案 9 :(得分:0)

这个想法是你不应该意外/无意地改变外面的类私有字段的值。 当您使用get和set时,这意味着您有意且有意地更改了类私有字段。

答案 10 :(得分:0)

将值设置为私有字段只会更改该字段,但在属性中将它们设置为可以处理其他参数,例如,您可以在设置值后调用方法

private string _email;
public string Email
{
    get
    {
        return this._email;
    }
    set
    {
        this._email = value;
        ReplaceList(); //**
    }
}




答案 11 :(得分:0)

简单来说,回答您的问题的是访问修饰符,即公共和私有。

如果您使用:

public int myInt;
public int MyInt 
{
     get { return myInt; }
     set { myInt = value }
}

然后MyInt属性和myInt变量都可以在要修改的项目中使用。 意思是,如果你的班级假设A是由类假设B继承的, 然后myInt和MyInt都可以修改,不能应用任何检查。 假设您希望myInt值可以在派生类中设置,如果某些特定条件通过。

这只能通过将字段私有和财产公开来实现。 因此,只有属性可用,并且可以根据该属性设置条件。

答案 12 :(得分:-1)

我无法相信11个答案,没有人说过这个:

并非所有私有字段都应作为公共属性公开。您当然应该将属性用于任何需要非私有的内容,但是您应该尽可能保持您的类私有。