C#自动属性与正常字段
在这个例子中,Foo.Something和Bar.Something之间有什么有效的区别吗C#自动属性与正常字段,c#,automatic-properties,C#,Automatic Properties,在这个例子中,Foo.Something和Bar.Something之间有什么有效的区别吗 class Foo { public string Something; } class Bar { public string Something{get; set;} } class Program { static void Main(string[] args) { var MyFoo = new Foo(); MyFoo.Som
class Foo
{
public string Something;
}
class Bar
{
public string Something{get; set;}
}
class Program
{
static void Main(string[] args)
{
var MyFoo = new Foo();
MyFoo.Something = "Hello: foo";
System.Console.WriteLine(MyFoo.Something);
var MyBar = new Bar();
MyBar.Something = "Hello: bar";
System.Console.WriteLine(MyBar.Something);
System.Console.ReadLine();
}
}
看来他们的行为完全一样。如果没有,为什么不使用Foo中的普通字段?
在java中,我们使用setter可以在不破坏代码的情况下强制执行新的不变量,并使用getter返回安全数据,但在c中,您始终可以将Foo重写为:
class Foo
{
private string _Something;
public string Something
{
get {
//logic
return _Something;
}
set {
//check new invariant
_Something = value;
}
}
}
而且旧代码不会被破坏。属性的getter和setter(包括自动的)具有方法调用成本。应避免使用公共字段,以便在访问时保持干净。
Foo。Something
是一个字段,栏。Something
是一个自动实现的属性。这是一个巨大的差异
您可以使用与字段相同的方式访问属性,但在访问属性时,会在内部调用set/get方法
因此,当您说myBar.Something=“asdf”
时,C编译器将其转换为对setter方法的调用:myBar.set\u Something(“asdf”)
。setter和getter方法会自动为您生成,以及实际值的支持字段
通过使用get和set方法将Foo.Something
更改为属性,您正在破坏二进制兼容性,这意味着您必须重新编译使用Foo.Something
的所有程序集,而它仍然是一个字段
看来他们的行为完全一样
不,他们没有
- 字段不能用于数据绑定(至少在某些绑定实现中)
- 以后可以为属性添加更多逻辑,而不破坏源代码或二进制兼容性
- 属性不能通过引用传递
- 不能向自动实现的属性添加初始值设定项
- 他们在反思方面显然会有所不同
- 从理论上讲,属性在逻辑上是API的一部分,而字段是实现细节
{get;set;}
会增加很多混乱
有关详细信息,请参见我的。1)您可以添加专用访问器以获取或设置并控制对属性的访问
public object MyProp {get; private set;}
你可以在任何地方阅读道具,但只能在课堂内写作
2) 您可以将一些逻辑连接到读/写属性。在现场的情况下,你不能做任何额外的事情
3) 不能序列化字段
公共字符串{get;set;}
只是语法糖;编译器实际上将其扩展为方法。因此,让所有get;设置代码>字段到处都是,只是为了它。你也可以用普通属性来做这件事。@Aschratt是的,但用字段你不能。当然,您可以使用字段指定readonly
,但这比private
setter要严格一些。对不起,我想问题是关于标准属性和自动属性之间的区别…:)没有恶意!你:应该避免使用公共字段我想公共只读字段可以吗?BCL使用它们。当然,这与原始问题无关。@JeppeStigNielsen我想是的。@JeppeStigNielsen:BCL很少使用只读实例字段。常数(即使是非常数常数,如果你明白我的意思的话)是另一回事。@JonSkeet我想你是对的。例如,KeyValuePair
不使用readonly
实例字段,它只使用get
实例属性(不过,反射找不到private
setters)。自动属性不能有(相当于)字段初始值设定项。例如,如果您最初想要Something=“initial”
属性,则必须使实例构造函数显式,并在该构造函数的主体中写入赋值(或所有构造函数,除非它们使用:此(…)
语法相互“链接”)。Jon Skeet走进一个问题,4票以上。@JeppeStigNielsen:对,对。@EaterofDeasters这与他基本无关,因为他已经远远超过了当天的代表名额。