C#3.0的自动属性 - 有用或没有?
注意:这是我刚刚开始C#时发布的。 随着2014年的知识,我可以真正地说,自动属性是曾经发生在C#语言的最好的事情之一。
我习惯于在C#中使用私有和公共字段来创build我的属性:
private string title; public string Title { get { return title; } set { title = value; } }
现在,在.NET 3.0中,我们获得了自动属性:
public string Title { get; set; }
我知道这是更多的哲学/主观的问题,但是有没有任何理由使用这些自动属性,除了保存每行的代码5行? 我个人的抱怨是这些属性隐藏了我的东西,我不是一个黑魔法的粉丝。
事实上,隐藏的专用字段甚至不会显示在debugging器中,这是可以的,因为get / set函数什么也不做。 但是当我想实际实现一些getter / setter逻辑时,我必须使用私有/公共对。
我看到了保存大量代码(一对六行)而不会丢失后来改变getter / setter逻辑的好处,但是我可以通过简单地声明一个公共字段“公共string标题” {get; 组; }块,从而甚至节省更多的代码。
那么,我在这里错过了什么? 为什么会有人想要使用自动属性?
我们一直在堆栈溢出中使用它们。
您也可能对“ 属性与公共variables”的讨论感兴趣。 恕我直言,这是真正的这是一个反应,为此,这是伟大的。
是的,它只是保存代码。 当你有很多东西的时候,阅读更容易。 他们写得更快,更容易维护。 保存代码总是一个好的目标。
你可以设置不同的范围:
public string PropertyName { get; private set; }
所以只能在课堂内改变属性。 这并不是真正的不变的,因为你仍然可以通过reflection来访问私有setter。
从C#6开始,您还可以创build真正的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"; }
在有很多成员的不可变类中,这节省了大量的额外代码。
使用字段而不是属性的三大缺点是:
- 你不能绑定到一个字段,而你可以到一个属性
- 如果你开始使用一个字段,你不能以后(很容易)把它们改成一个属性
- 有一些属性可以添加到不能添加到字段的属性中
我个人喜欢汽车性能。 保存代码行有什么问题? 如果你想在getter或setter中做东西,那么稍后将它们转换为普通属性是没有问题的。
正如你所说,你可以使用字段,如果你想添加逻辑给后者,你可以将它们转换成属性。 但是,这可能会导致任何使用reflection(也可能在其他地方)的问题。
此外,这些属性允许您为getter和setter设置不同的访问级别,这是您无法使用字段的。
我想这跟var关键字一样。 个人喜好的问题。
来自C ++创build者Bjarne Stroustrup:
我特别不喜欢有很多get和set函数的类。 这往往表明它本来不应该是一个阶级。 这只是一个数据结构。 如果它确实是一个数据结构,那么把它变成一个数据结构。
你知道吗? 他是对的。 多久你只是简单地将私有字段包装在一个get和set中,而没有在get / set中做任何事情,只是因为它是“面向对象”的事情。 这是微软解决这个问题的方法; 他们基本上是公共领域,你可以绑定到。
有一件事似乎没有人提到过,自动属性对于不可变的对象(通常是不可变的结构)来说是不可用的。 因为你真的应该这样做:
private readonly string title; public string Title { get { return this.title; } }
(通过传递的参数在构造函数中初始化该字段,然后是只读的。)
所以这比简单的get
/ private set
有优势。
我总是创build属性而不是公共字段,因为您可以在接口定义中使用属性,所以不能在接口定义中使用公共字段。
自动属性和C#中的其他任何东西一样都是黑魔法。 一旦你把它编译到IL而不是它被扩展到一个正常的C#属性,它比许多其他的语言结构less得多的黑魔法。
我一直使用自动属性。 在C#3之前,我不能打扰所有的input,只是使用公共variables。
我唯一想念的是能够做到这一点:
public string Name = "DefaultName";
您必须将默认值转换为具有属性的构造函数。 单调乏味:-(
我认为任何直观和减less代码行的构造是一个很大的优点。
这些function使得像Ruby这样的语言function非常强大(即dynamicfunction,这也有助于减less多余的代码)。
Ruby始终如此:
attr_accessor :my_property attr_reader :my_getter attr_writer :my_setter
我与他们唯一的问题是,他们不够远。 在编译器的同一版本中添加了自动属性,添加了部分方法。 为什么他们不把这两个放在一起超出了我。 一个简单的“部分On <PropertyName>改变”将使这些事情真的非常有用。
这很简单,它很短,如果你想在属性的主体内部创build一个真正的实现,它不会破坏你的types的外部接口。
就如此容易。
这里要注意的一点是,就我的理解,这只是 C#3.0端的语法糖,意味着编译器生成的IL是相同的。 我同意避免黑魔法,但同样的道理,同样的事情通常是一件好事。
在我看来,你应该总是使用自动属性,而不是公共领域。 这就是说,这是一个妥协:
从内部字段开始,使用用于属性的命名约定。 当你第一次
- 需要从组件外部进入现场,或者
- 需要将逻辑连接到getter / setter
做这个:
- 重命名该字段
- 使其私密
- 添加公共财产
你的客户端代码不需要改变。
但是,有一天,你的系统会增长,你会分解成单独的程序集和多个解决scheme。 当这种情况发生时,任何暴露的领域都会回来困扰你,因为正如杰夫所说, 将公共领域改为公共财产是一个突破API的变化 。
我使用CodeRush,它比自动属性更快。
去做这个:
private string title; public string Title { get { return title; } set { title = value; } }
总共需要八个击键。
那么与代码片段相同名称的自动属性将是总共七个按键;)
@Domenic:我不明白..你不能用自动属性来做这个吗?
public string Title { get; }
要么
public string Title { get; private set; }
这是你所说的吗?
我对自动属性最大的抱怨是,他们的目的是为了节省时间,但我经常发现我不得不在晚些时候将它们扩展成全面的属性。
什么VS2008是缺less爆炸自动属性重构。
我们有一个封装字段重构的事实,使我更快地使用公共字段的方式。
- 亚音速与NHibernate
- 为什么LINQ JOIN比用WHERE连接要快得多?
- 从HttpWebRequest和HttpWebResponse获取Http状态代码(200,301,404等)
- 使用System.IO.Compression在内存中创build一个ZIP存档
- NHibernate.MappingException:没有persister:XYZ
- 如何添加具有值的新列到现有DataTable?
- 如何从xsd生成.NET 4.0类?
- 因为它有一个DefiningQuery,并且<ModificationFunctionMapping>元素中不存在<InsertFunction>元素
- “断点目前不会受到打击。 源代码与原始版本不同。“这是什么意思?