我刚刚开始学习c#,而且我对getter和setter的简写有点挣扎 .
据我了解,下面的两种方法是等效的 . 它是否正确?
//Method 1
public string name { get; set; }
//Method 2
private string name
public string getName() { return name;}
public string setName(string newName) { this.name = newName; }
其次,如果我们想要getter / setter和实例变量上的不同访问修饰符,这是如何工作的 . 以下代码错误,告诉我访问者必须比属性更具限制性,并且我不能为烦恼的访问器指定修饰符 . 有人可以澄清一下吗?
private int maxTime { public get; public set; }
编辑:澄清,我没有具体的目标,只有理解 . 我不明白这个简写符号是做什么的 . 在其他语言中,我有私有实例变量,并使用公共getter和setter来管理这些实例变量 . 如果我自己写出方法,它就允许这样做,但不是用这个简写符号 . 为什么是这样?
编辑2:检查我的理解的最后一个问题 . 下面的两个代码片段都使用属性来管理maxTime变量 . 两者之间的唯一区别是风格 . 它是否正确?
private int maxTime;
public int MaxTime{ get; set; }
VS
private int maxTime;
public int MaxTime
{
get { return maxTime; }
set { maxTime= value; }
}
5 回答
以上两种方法相当于 not .
比较它们会更准确:
如果你想玩访问修饰符,比如使
get
为public,set
为private,那么你会这样做:关于Auto-Implemented Properties的更多信息以及幕后发生的编译器魔术 .
您可以编写一个将填充私有字段的属性,而不是错误的
private int maxTime { public get; public set; }
:当您想要获取或设置maxTime的值时应用逻辑时,这非常有用 . 如果没有,一个简单的速记属性将做:
您可以创建一个具有公共getter但私有setter的属性,如下所示:
这对于只读属性很有用,通常该属性在类的构造函数中填充 .
你甚至可以创建一个属性,其中setter是公共的,但是getter是私有的,尽管我无法想象这会有用的任何场景 . 而且,代码标准声称这样的东西应该是一种方法,而不是一种 property . (read this)
编辑2中你的问题的答案是否定的 .
第一个代码永远不会改变私有int
maxTime
,而第二个代码确实如此 . 但是,如果你的 class 只使用属性MaxTime
,那么它们在功能上是等价的 .更新:
从c#6开始,你可以在没有setter的情况下编写速记属性:
这些属性只能在构造函数中初始化,或者硬编码如下:(也是c#6的新功能)
这对于不可变属性很有用(与readonly属性不同,这样的属性的值在初始化后甚至在托管类内部也不会改变 .
当您使用方法1中的属性(公共字符串名称{get; set;})时,编译器会自动生成私有后备字符串变量以及公共getter和setter方法 .
一般的想法是将字段设为私有,并且只允许通过公共getter / setter方法进行访问 . 因此,如果使用方法2,则声明变量private .
我建议使用ILDASM来仔细阅读生成的IL,它有助于了解幕后发生了什么 .
第二个错误就是编译器所说的 . 构造的可见性必须一致
你所拥有的是Auto-Implemented property,它内部有一个支持私有字段(以及get / set的编译时方法) .
在C#代码中,这相当于:
在编译时,get / set被转换为方法调用,有点类似于你所拥有的 .
对于:
错误很明显,您不能拥有比属性本身更少限制的访问说明符 . 例如,如果您希望
public
属性具有public
get
,但如果您只想允许在类中设置属性,则可以执行以下操作:您还应该看到:.Net Naming conventions,如果您遵循这一点会更好,因此您可以将您的属性名称以大写字母开头 .
第一种方法是C#语法糖,用于自动实现的属性 . 当您编译它时,它提供适当的访问器的实现 .
第二个例子是不同的 . 在这里,您有一个公共范围字段(通常是因为封装原则而禁止使用)和两个访问变量的方法 . 有's a subtle difference in semantic usage; typically properties are used to expose state, whereas a method normally indicates that the method has some computation behind it and isn' t只是返回或更改当前状态(同样,这是一个约定,而不是一个快速的规则)方法通常使用VerbAction命名(public Thing GetAThing(){}) .
自动生成的属性可以具有不同的访问修饰符,但只能使得get或set的可访问性低于整体修饰符 .