属性vs公共成员变量

时间:2012-08-08 22:55:05

标签: c# properties private public

  

可能重复:
  What is the difference between a field and a property in C#

我是一名初学程序员,我已经阅读了所有关于类属性的内容。书籍声明属性允许您间接访问成员变量。好的,那么是什么让它与公众直接公开并直接访问它有何不同?

以下是Jesse Liberty学习C#3.0的引用:

  

例如,您可能需要外部   类可以读取值,但不能更改它;或者你可能想写   一些代码,以便内部字段只能接受某个范围内的值。如果你   授予外部类免费访问您的成员字段,您无法控制其中任何一个。

我不明白他在这说什么。有人可以进一步解释这一点,或举例说明为什么我要使用财产而不是公开该字段。据我所知,现在他们都会完成同样的事情......所以我显然在这里遗漏了一些东西。

6 个答案:

答案 0 :(得分:10)

他说属性可以提供getter而不是setter,因此将它们设置为只读(例如)

属性只是一种方法的语法糖,例如

public int SomeProperty { get; set; }

只是糖的

private int _someProperty;

public int SomeProperty_get() 
{
   return _someProperty;
}

public void SomeProperty_set(int value) 
{
   _someProperty = value;
}

这意味着属性设置者/获取者可以应用仅仅公共领域不能

的逻辑

编辑:我不确定CLR为自动属性提供支持字段的字段名称 - 这只是一个例子:)

EDIT2:

只读属性的示例:

public int SomeProperty { get; }

最后是公开阅读 - 私人写作(针对autoproperties)

public int SomeProperty { get; private set; }

当您无法在以下方式键入支持字段时非常有用:)

请记住,如果您希望将逻辑应用于成员,那么属性就是可行的方法。这是许多框架工作的方式(例如,通过使用属性来告诉某种对象管理器某些内容已发生变化,使用公共字段无法实现,从而跟踪'脏'对象)

答案 1 :(得分:10)

到目前为止提供的其他答案提供了accessor / mutator逻辑优点的详细信息,但似乎都错过了关于对象封装的意识形态观点。

您会看到,类成员字段是一个实现细节。例如,如果您有一个表示集合的类,那么您可以将其实现为链接列表(并通过公共字段公开根节点),或者您可以将其实现为可调整大小的数组并公开index0成员。 / p>

揭示实现细节的问题在于您丢失了类与其使用者之间的任何类型的已定义接口。通过确保所有操作都通过定义的方法(由类本身控制)完成,您可以更轻松地使用并提供长期观点。例如,您可以更轻松地将集合实现从一种类型(链接列表)转换为另一种类型(数组),而不会破坏与您的类“消费者”的任何合同。

不要担心琐碎的访问器/ mutator方法对性能的影响:JIT编译器将内联属性方法。如果您将运行一些基准测试,您将看到属性与字段的性能相同。

答案 2 :(得分:7)

属性可能有副作用,它们围绕'getter'和'setter'方法提供语法糖。

public class MyClass {

   int sizeValue = 0;

   public int Size {
      get {
         return sizeValue;
      }
      set {
         if ( value < 10 ) throw new Exception("Size too small");
         sizeValue = value;
      }
   }
}

属性也可以为get和set提供不同级别的保护,你不能用字段来做。

public class MyOtherClass {

   // only this object can set this.
   public int Level {
      get; private set; 
   }

   // only things in the same assembly can set this.
   public string Name {
      get; internal set;
   }
}

答案 3 :(得分:3)

“属性”和“成员访问”之间存在许多重要差异。

最重要的是,您可以通过属性将成员设为只读(您可以访问该状态,但无法更改它)。就像Java中的“getter()”和“setter()”方法一样。

您还可以从属性返回计算值(“动态”生成值,就像它是变量一样)。

答案 4 :(得分:1)

可以配置属性以便:

它们是只读的,Public MyProp {get;}

它们是只写Public MyProp {set;}

它们可被外部对象读取,但只能由类的内部设置

公开MyProp {get; private set;}

正如其他人发布的那样,您也可以将逻辑放入您的getter和setter中。例如,在允许属性下注设置为新值之前,您可以检查该值是否可接受。

你不能用公共领域做任何事情。

基本上,公共领域是你可以拥有的最愚蠢的财产。鉴于.Net现在允许为您的属性自动填充字段。没有充分的理由再使用公共领域了。

答案 5 :(得分:0)

如果您有Public Int MyAge 我可以将它设置为-200或20,000,你无能为力。

如果使用属性,则可以检查年龄是否介于0到150之间。

编辑:根据IanNorton的例子(伙计,那很快)