C#3.0自动属性-是否有用?
注意:这是我刚开始使用C#时发布的。凭借2014年的知识,我可以真正地说出自动属性是该语言有史以来最好的事情之一。
我习惯于在私有和公共领域中创建我的属性:
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 Title"而无需{放; }块,从而节省更多代码。
那么,我在这里想念的是什么?为什么有人实际上要使用自动属性?
解决方案
回答
我个人喜欢自动属性。保存代码行怎么了?如果我们想在getter或者setter中做一些事情,以后再将它们转换为普通属性是没有问题的。
如我们所说,我们可以使用字段,并且如果我们想向它们添加逻辑,则可以将它们转换为属性。但这可能会在使用反射时(以及可能在其他地方使用)带来问题。
此外,这些属性还允许我们为getter和setter设置不同的访问级别,而这是我们不能使用字段的。
我想它与var关键字相同。个人喜好问题。
回答
使用字段而不是属性的三个主要缺点是:
- 我们无法将数据绑定到字段,而可以绑定到属性
- 如果我们开始使用字段,则以后不能(轻松地)将其更改为属性
- 我们可以将某些属性添加到无法添加到字段的属性中
回答
我们一直在Stack Overflow中使用它们。
我们可能还对属性与公共变量的讨论感兴趣。恕我直言,这确实是对它的反应,为此,它很棒。
回答
我一直都在使用自动属性。在C#3之前,我不会为所有类型感到烦恼,而只是使用了公共变量。
我唯一想念的是能够做到这一点:
public string Name = "DefaultName";
我们必须将默认值转移到带有属性的构造函数中。乏味的:-(
回答
我认为任何直观且能减少代码行的构造都是一个很大的优点。
这些功能使Ruby之类的语言如此强大(具有动态功能,这也有助于减少多余的代码)。
Ruby一直这样:
attr_accessor :my_property attr_reader :my_getter attr_writer :my_setter
回答
我对他们的唯一问题是他们走得不够远。同一版本的编译器增加了自动属性,增加了部分方法。为什么他们没有把两者放在一起,这超出了我。一个简单的"部分On <PropertyName> Changed"将使这些事情真的非常有用。
回答
是的,它只是保存代码。拥有大量负载时,阅读起来容易得多。它们编写起来更快,维护起来也更容易。保存代码始终是一个好目标。
我们可以设置不同的范围:
public string PropertyName { get; private set; }
这样,该属性只能在类内部进行更改。这并不是真正不变的,因为我们仍然可以通过反射来访问私有设置器。
从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"; }
在具有很多成员的不可变类中,这节省了大量多余的代码。
回答
据我了解,这里要注意的一件事是C3.0端的语法糖,这意味着编译器生成的IL是相同的。我同意避免使用黑魔法,但是对于同一件事,所有相同,更少的行通常是一件好事。
回答
我认为,应该始终使用自动属性而不是公共字段。也就是说,这是一个折衷方案:
使用要用于属性的命名约定从内部字段开始。当我们第一次
- 需要从其组件外部访问该字段,或者
- 需要将逻辑添加到getter / setter
做这个:
- 重命名字段
- 设为私人
- 添加公共财产
客户代码无需更改。
但是,总有一天,系统会不断增长,并将其分解为单独的程序集和多个解决方案。发生这种情况时,任何公开的字段都会再次困扰我们,因为正如Jeff所提到的,将公共字段更改为公共属性是API的重大更改。
回答
自动属性与C#中的其他任何事物一样都是黑魔法。一旦我们从编译为IL而不是首先将其扩展为正常Cproperty的角度来考虑它,它就比许多其他语言构造少了很多黑魔法。
回答
我使用CodeRush,它比自动属性要快。
去做这个:
private string title; public string Title { get { return title; } set { title = value; } }
总共需要八次击键。
回答
好的,使用代码片段,具有相同名称的自动属性总共将是七个击键;)
回答
似乎没有人提到的一件事是,不幸的是,自动属性对不可变对象(通常是不可变结构)没有用。为此,我们确实应该这样做:
private readonly string title; public string Title { get { return this.title; } }
(该字段在构造函数中通过传递的参数进行初始化,然后为只读。)
因此,这比简单的"获取" /"私有集"自动属性具有优势。
回答
@Domenic:我不明白..你不能用自动属性吗?:
public string Title { get; }
或者
public string Title { get; private set; }
这就是我们所指的吗?
回答
这很简单,很简短,如果我们想在属性主体内部的某个位置下创建一个真正的实现,则不会破坏我们类型的外部接口。
就如此容易。
回答
来自C ++的创建者Bjarne Stroustrup:
I particularly dislike classes with a lot of get and set functions. That is often an indication that it shouldn't have been a class in the first place. It's just a data structure. And if it really is a data structure, make it a data structure.
一个你知道吗?他是对的。我们只是多频繁地将私有字段包装在一个get和set中,而实际上没有在get / set中做任何事情,仅仅是因为这是"面向对象"的事情。这是Microsoft解决该问题的方法。它们基本上是可以绑定的公共字段。
回答
我对自动属性的最大抱怨是,它们旨在节省时间,但是我经常发现我后来不得不将它们扩展为完整的属性。
VS2008缺少的是爆炸自动属性重构。
我们具有封装字段重构的事实使我可以更快地使用公共字段。
回答
我总是创建属性而不是公共字段,因为我们可以在接口定义中使用属性,而不能在接口定义中使用公共字段。