如果在C#自动属性中必须获取和设置get和set,为什么我必须打扰指定"get; set;" 什么?
因为您可能需要只读属性:
public int Foo { get; private set; }
或只写属性:
public int Foo { private get; set; }
错误:属性或索引器不能作为out或ref参数传递
如果您没有指定,{get; set;}
则编译器将不知道它是字段还是属性.这很重要,因为当它们"看起来"相同时,编译器会以不同的方式对待它们.例如,在属性上调用"InitAnInt"会引发错误.
class Test { public int n; public int i { get; set; } public void InitAnInt(out int p) { p = 100; } public Test() { InitAnInt(out n); // This is OK InitAnInt(out i); // ERROR: A property or indexer may not be passed // as an out or ref parameter } }
你不应该在类上创建公共字段/变量,你永远不知道什么时候你想要改变它来获取和设置访问器,然后你不知道你将破坏什么代码,特别是如果你有针对您的API编程的客户.
你也可以为get和set设置不同的访问修饰符,例如{get; private set;}使get public和set private成为声明类.
我想我会在这个主题上分享我的发现.
编码如下所示的属性是.net 3.0快捷方式调用" 自动实现的属性 ".
public int MyProperty { get; set; }
这可以节省一些打字.声明属性的漫长方法是这样的:
private int myProperty; public int MyProperty { get { return myProperty; } set { myProperty = value; } }
当您使用"自动实现的属性"时,编译器会生成代码以连接get并设置为某个"k_BackingField".下面是使用Reflector的反汇编代码.
public int MyProperty { [CompilerGenerated] get { return this.k__BackingField; } [CompilerGenerated] set { this. k__BackingField = value; } }
来自IL的反汇编C#代码
还连接了setter和getter的方法.
[CompilerGenerated] public void set_MyProperty(int value) { this.k__BackingField = value; } [CompilerGenerated] public int get_MyProperty() { return this. k__BackingField; }
来自IL的反汇编C#代码
声明只读自动实现属性时,通过将setter设置为private:
public int MyProperty { get; private set; }
所有编译器都将" set " 标记为private.setter和getter方法也是如此.
public int MyProperty { [CompilerGenerated] get { return this.k__BackingField; } private [CompilerGenerated] set { this. k__BackingField = value; } }
来自IL的反汇编C#代码
所以我不确定为什么框架需要get; 并设定; 在一个自动实现的属性.如果没有提供,他们可能没有写过set和setter方法.但是可能有一些编译器级别的问题使得这很困难,我不知道.
如果你看一下声明只读属性的漫长道路:
public int myProperty = 0; public int MyProperty { get { return myProperty; } }
然后看看反汇编的代码.安装员根本不存在.
public int Test2 { get { return this._test; } } public int get_Test2() { return this._test; }
来自IL的反汇编C#代码
因为你需要一些方法来区分它与普通字段.
拥有不同的访问修饰符也很有用,例如
public int MyProperty { get; private set; }