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