Ben*_*Ben 44 c# automatic-properties c#-3.0
如果在C#自动属性中必须获取和设置get和set,为什么我必须打扰指定"get; set;" 什么?
Bri*_*sio 64
因为您可能需要只读属性:
public int Foo { get; private set; }
Run Code Online (Sandbox Code Playgroud)
或只写属性:
public int Foo { private get; set; }
Run Code Online (Sandbox Code Playgroud)
Bin*_*ier 52
错误:属性或索引器不能作为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
}
}
Run Code Online (Sandbox Code Playgroud)
你不应该在类上创建公共字段/变量,你永远不知道什么时候你想要改变它来获取和设置访问器,然后你不知道你将破坏什么代码,特别是如果你有针对您的API编程的客户.
你也可以为get和set设置不同的访问修饰符,例如{get; private set;}使get public和set private成为声明类.
Ron*_*huk 17
我想我会在这个主题上分享我的发现.
编码如下所示的属性是.net 3.0快捷方式调用" 自动实现的属性 ".
public int MyProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)
这可以节省一些打字.声明属性的漫长方法是这样的:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
Run Code Online (Sandbox Code Playgroud)
当您使用"自动实现的属性"时,编译器会生成代码以连接get并设置为某个"k_BackingField".下面是使用Reflector的反汇编代码.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
[CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
Run Code Online (Sandbox Code Playgroud)
来自IL的反汇编C#代码
还连接了setter和getter的方法.
[CompilerGenerated]
public void set_MyProperty(int value)
{
this.<MyProperty>k__BackingField = value;
}
[CompilerGenerated]
public int get_MyProperty()
{
return this.<MyProperty>k__BackingField;
}
Run Code Online (Sandbox Code Playgroud)
来自IL的反汇编C#代码
声明只读自动实现属性时,通过将setter设置为private:
public int MyProperty { get; private set; }
Run Code Online (Sandbox Code Playgroud)
所有编译器都将" set " 标记为private.setter和getter方法也是如此.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
private [CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
Run Code Online (Sandbox Code Playgroud)
来自IL的反汇编C#代码
所以我不确定为什么框架需要get; 并设定; 在一个自动实现的属性.如果没有提供,他们可能没有写过set和setter方法.但是可能有一些编译器级别的问题使得这很困难,我不知道.
如果你看一下声明只读属性的漫长道路:
public int myProperty = 0;
public int MyProperty
{
get { return myProperty; }
}
Run Code Online (Sandbox Code Playgroud)
然后看看反汇编的代码.安装员根本不存在.
public int Test2
{
get
{
return this._test;
}
}
public int get_Test2()
{
return this._test;
}
Run Code Online (Sandbox Code Playgroud)
来自IL的反汇编C#代码
Cri*_*rdo 16
因为你需要一些方法来区分它与普通字段.
拥有不同的访问修饰符也很有用,例如
public int MyProperty { get; private set; }
Run Code Online (Sandbox Code Playgroud)