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.Something = "Hello: foo";
System.Console.WriteLine(MyFoo.Something);
var MyBar = new Bar();
MyBar.Something = "Hello: bar";
System.Console.WriteLine(MyBar.Something);
System.Console.ReadLine();
}
}
AFAIK他们的行为完全相同。如果他们为什么不在Foo中使用普通的字段? 在java中,我们使用setter来强制执行新的不变量而不会破坏代码和getter来返回安全数据但是在c#中你总是可以将Foo重写为:
class Foo
{
private string _Something;
public string Something
{
get {
//logic
return _Something;
}
set {
//check new invariant
_Something = value;
}
}
}
旧代码不会被破坏。
答案 0 :(得分:8)
AFAIK他们的行为完全相同。
不,他们不会。
在c#中你总是可以将Foo重写为:[...]
如果您不关心二进制或源兼容性,那么你可以,是的。在某些情况下,确实不是一个问题 - 在其他情况下,这是一个非常非常严重的问题。为什么不从一开始就选择公开您的API而不是您的实施细节?在您的代码中添加{ get; set; }
并不像添加更多混乱...
有关更多咆哮,请参阅我的article on this。
答案 1 :(得分:1)
Foo.Something
是一个字段,Bar.Something
是一个自动实现的属性。这是一个巨大的差异。
您可以像访问字段一样访问属性,但在访问属性时会在内部调用set / get方法。
因此,当您说myBar.Something = "asdf"
时,C#编译器会将其转换为对setter方法的调用:myBar.set_Something("asdf")
。将自动为您生成setter和getter方法,以及实际值的支持字段。
通过使用get和set方法将Foo.Something
更改为属性,您将破坏二进制兼容性,这意味着当它仍然是字段时,您将不得不重新编译使用Foo.Something
的所有程序集。
答案 2 :(得分:0)
属性的getter和setter(包括自动的)具有方法调用成本。应该避免使用公共字段,以便通过访问保持干净。
答案 3 :(得分:0)
1)您可以添加私人访问者来获取或设置和控制对财产的访问权。
public object MyProp {get; private set;}
你可以在任何地方阅读道具,但只能在课堂内写作
2)您可以将某些逻辑连接到读/写属性。如果是现场你不能做任何额外的事情
3)您无法序列化字段
答案 4 :(得分:0)
public string Something{get; set;}
只是语法糖;编译器实际上将其扩展为方法。因此,只要为了它而将所有get; set;
字段放在所有地方是没有意义的。