4

可能重复:
C# 中的属性和变量有什​​么区别

几周前我开始使用 C#,这确实困扰着我。C# 允许这些所谓的“神奇”getter 和 setter,也称为“语法糖”。所以,我可以做这样的事情:

public int myInt { get; set; }

但从封装的角度来看,这是没有意义的。一方面,数据成员是public,我可以使用点运算符获取/设置它。但是,如果我这样做:

private int myInt { get; set; }

我根本无法访问它,因为myInt is inaccessible due to protection level. 这实际上在做什么?我认为这应该是完成数据封装的一种简单方法,所以我不必这样做:

private int myInt;
public void setMyInt(int i) { myInt = i; }
public int getMyInt() { return myInt; }

但事实并非如此。据我所知,我只是将这些变量公开。我想也许我可以做类似的事情

public int myInt { get; }

所以客户可以get,但不能set,但不,仍然允许公共访问。那么给了什么?

编辑 我不想做任何具体的事情,我只是想了解这实际上是如何工作的。澄清:

制作变量public不会完成封装,尤其是当我可以使用点运算符访问它时。为变量编写 getter 和 setterprivate可以让您对变量进行更改,但可以更好地控制实际发生的方式。

4

5 回答 5

7

目的是您通过将来的修改来维护封装。

如果您最初使用自动 getter 和 setter 编写类:

public int Count { get; set; }

然后,如果您将其更改为,它将保持完全相同的外部接口

public int Count {
    get { /* very complicated logic */ }
    set { /* even more complicated logic */ }
}

自动的最初只是为了帮助您处理简单的属性。

于 2012-07-25T14:36:36.880 回答
6

你正在尝试写

public int MyInt { get; private set; }

编辑:自动实现属性的重点不是提供额外的封装,而是避免字段。
如果您创建一个具有公共字段 ( publit int MyInt;) 的类,并且有人使用该字段,则以后不能将其更改为属性,否则您将破坏任何使用它的已编译程序集。

使用自动属性为您提供与字段相同的简单性和简洁性,但允许您稍后用成熟的属性(包含附加逻辑)替换它而不会破坏任何内容。

于 2012-07-25T14:34:18.900 回答
6

这种“神奇”的 getter 和 setter 就像您在 Java 中所做的那样,实际上最终会创建方法。因此is,IMO 以更简洁的外观保持了这一点。

属性本身,即使声明public int Property {get;set;}为例如,实际上也有一个支持字段和getter一个setter方法。

看这个人为的例子:

class A
{
   public int ID {get;set;}
}

现在,当您执行以下操作时:

A a = new A();
a.ID=5;

生成的 IL 代码如下所示:

A.get_ID:    //getter method
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+A.<ID>k__BackingField 
IL_0006:  ret         

A.set_ID:   //setter method
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+A.<ID>k__BackingField
IL_0007:  ret         

所以是的,做a.ID=5; 看起来它是直接访问一个成员变量,但它实际上是在调用一个方法;在这种情况下,set_ID方法。

于 2012-07-25T14:35:33.650 回答
0

您只是将其公开 - 如果您想指定私有集,您可以执行以下操作:

   int myInt { get; private set; }
于 2012-07-25T14:35:05.230 回答
0

你可以这样做,这非常有用:

公共 int myInt { 获取;私人套装;}

于 2012-07-25T14:35:48.970 回答