15

可能重复:
C#中的字段和属性有什么区别

我是一个初级程序员,我已经阅读了所有关于类属性的内容。书籍指出属性允许您间接访问成员变量。好的,那么与仅将字段公开并直接访问它有什么不同呢?

这是 Jesse Liberty 的 Learning C# 3.0 中的一段话:

例如,您可能希望外部类能够读取一个值,但不能更改它;或者您可能想要编写一些代码,以便内部字段只能接受特定范围内的值。如果您授予外部课程对您的成员字段的免费访问权限,您将无法控制其中的任何内容。

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

4

6 回答 6

11

到目前为止提供的其他答案提供了访问器/突变器逻辑优势的详细信息,但似乎都错过了关于对象封装的思想观点。

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

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

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

于 2012-08-08T23:07:52.077 回答
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 为自动属性提供支持字段的字段名称 - 这只是一个示例 :)

编辑2:

只读属性的示例:

public int SomeProperty { get; }

最后是公共读取 - 私人写入(用于自动属性)

public int SomeProperty { get; private set; }

当您不想在其中键入支持字段时非常有用:)

请记住,如果您希望将逻辑应用于成员,那么属性就是要走的路。这是许多框架的工作方式(例如,通过使用属性来跟踪“脏”对象以告诉某种对象管理器某些内容已更改,使用公共字段这是不可能的)

于 2012-08-08T22:59:00.420 回答
9

属性可能有副作用,它们围绕“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;
   }
}
于 2012-08-08T22:58:15.303 回答
3

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

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

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

于 2012-08-08T22:57:26.707 回答
1

可以配置属性,以便:

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

它们是只写的Public MyProp {set;}

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

上市MyProp {get; private set;}

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

您不能对公共字段执行任何操作。

基本上,公共字段是您可以拥有的最愚蠢的属性。鉴于 .Net 现在允许为您的属性自动备份字段。不再有充分的理由使用公共字段。

于 2012-08-08T23:05:26.867 回答
0

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

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

编辑:根据 IanNorton 的示例(伙计,这很快)

于 2012-08-08T22:59:27.763 回答