注意:这是在我开始使用C#时发布的。凭借2014年的知识,我可以真正地说,自动属性是C#语言中发生过的最好的事情。
我习惯使用私有和公共字段在C#中创建我的属性:
private string title;
public string Title
{
get { return title; }
set { title = value; }
}
现在,使用.NET 3.0,我们获得了自动属性:
public string Title { get; set; }
我知道这更像是一个哲学/主观问题,但除了为每个字段保存五行代码之外,是否有任何理由使用这些自动属性?我个人的抱怨是,那些属性隐藏了我的东西,我不是黑魔法的忠实粉丝。
实际上,隐藏的私有字段甚至没有出现在调试器中,考虑到get / set函数什么都不做,这是可以的。但是当我想实际实现一些getter / setter逻辑时,我还是必须使用私有/公共对。
我看到了我节省了大量代码(一对六行)而不会失去以后更改getter / setter逻辑的能力的好处,但是我再次通过简单地声明一个公共字段“Public string”就可以做到这一点。标题“不需要{get;组;阻止,因此甚至可以保存更多代码。
那么,我在这里错过了什么?为什么有人真的想要使用自动属性?
答案 0 :(得分:113)
我们一直在Stack Overflow中使用它们。
您可能也对Properties vs. Public Variables的讨论感兴趣。恕我直言,这真的是对此的反应,为此目的,它很棒。
答案 1 :(得分:59)
是的,只是保存代码。当你有大量的东西时,阅读起来更容易。它们编写起来更快,更易于维护。保存代码始终是一个很好的目标。
您可以设置不同的范围:
public string PropertyName { get; private set; }
这样只能在类中更改属性。这不是真正不可变的,因为您仍然可以通过反射访问私有的setter。
从C#6开始,您还可以创建真正的readonly
属性 - 即在构造函数之外无法更改的不可变属性:
public string PropertyName { get; }
public MyClass() { this.PropertyName = "whatever"; }
在编译时将成为:
readonly string pName;
public string PropertyName { get { return this.pName; } }
public MyClass() { this.pName = "whatever"; }
在具有大量成员的不可变类中,这可以节省大量多余的代码。
答案 2 :(得分:44)
使用字段而不是属性的三大缺点是:
答案 3 :(得分:28)
我个人喜欢自动财产。保存代码行有什么问题?如果你想在getter或setter中做一些事情,以后将它们转换为普通属性是没有问题的。
正如你所说,你可以使用字段,如果你想稍后为它们添加逻辑,你可以将它们转换为属性。但这可能会出现任何使用反射的问题(可能还有其他地方?)。
此外,这些属性还允许您为getter和setter设置不同的访问级别,而不能使用字段。
我猜它与var关键字相同。个人偏好问题。
答案 4 :(得分:28)
来自Bjarne Stroustrup,C ++的创建者:
我特别不喜欢有很多get和set函数的类。这通常表明它本来不应该是一个阶级。它只是一个数据结构。如果它确实是一个数据结构,那就把它变成一个数据结构。
你知道吗?他是对的。你经常在get和set中简单地包装私有字段,而不是实际在get / set中做任何事情,只是因为它是“面向对象”的事情。这是微软解决问题的方法;它们基本上是你可以绑定的公共领域。
答案 5 :(得分:18)
有人似乎没有提到的一件事是,不幸的是,自动属性对于不可变对象(通常是不可变的结构)没有用处。因为你真的应该这样做:
private readonly string title;
public string Title
{
get { return this.title; }
}
(通过传递的参数在构造函数中初始化字段,然后是只读的。)
因此,这比简单的get
/ private set
autoproperty更具优势。
答案 6 :(得分:12)
我总是创建属性而不是公共字段,因为您可以在接口定义中使用属性,不能在接口定义中使用公共字段。
答案 7 :(得分:8)
自动属性与C#中的任何其他内容一样具有黑魔法。一旦你从编译到IL而不是将它扩展到普通的C#属性的角度来考虑它,那么它的黑魔法就比许多其他语言结构要少得多。
答案 8 :(得分:5)
我认为任何直观的构造都会减少代码行是一个很大的优势。
这些特性使Ruby这样的语言如此强大(动态特性,也有助于减少多余的代码)。
Ruby一直都这样:
attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter
答案 9 :(得分:5)
我一直使用自动属性。在C#3之前,我不会被所有打字困扰,而只是使用了公共变量。
我唯一想念的是能够做到这一点:
public string Name = "DefaultName";
您必须将默认值转换为具有属性的构造函数。乏味的: - (
答案 10 :(得分:2)
我与他们唯一的问题是他们走得不够远。添加自动属性的编译器的同一版本,添加了部分方法。为什么他们没有将两者结合在一起超出了我的范围。一个简单的“部分On< PropertyName> Changed”会使这些事情变得非常有用。
答案 11 :(得分:2)
这很简单,它很简短,如果你想在属性内部的某个地方创建一个真正的实现,它不会破坏你的类型的外部接口。
就这么简单。
答案 12 :(得分:1)
这里要注意的一点是,根据我的理解,这是C#3.0端的只是语法糖,这意味着编译器生成的IL是相同的。我同意避免黑魔法,但同样的,相同的东西通常是一件好事。
答案 13 :(得分:1)
在我看来,您应该始终使用自动属性而不是公共字段。那就是说,这是妥协:
使用您用于属性的命名约定,从internal字段开始。当你第一次
这样做:
您的客户端代码无需更改。
但是,有一天,您的系统将会增长,您将把它分解为单独的程序集和多个解决方案。当发生这种情况时,任何暴露的字段都会回来困扰你,因为正如杰夫所说,changing a public field to a public property is a breaking API change。
答案 14 :(得分:0)
我使用CodeRush,它比自动属性更快。
要做到这一点:
private string title;
public string Title
{
get { return title; }
set { title = value; }
}
总共需要八次击键。
答案 15 :(得分:0)
使用代码片段,同名的自动属性总共会有七次击键;)
答案 16 :(得分:0)
@Domenic:我不明白..你不能用自动属性做这个吗?:
public string Title { get; }
或
public string Title { get; private set; }
这是你指的是什么?
答案 17 :(得分:0)
我对自动属性的最大抱怨是它们旨在节省时间,但我经常发现我必须在以后将它们扩展为完整的属性。
VS2008缺少的是爆炸自动属性重构。
我们拥有封装字段重构这一事实使我更快地使用公共字段。