C#3.0自动属性 ​​- 有用与否?

时间:2008-08-12 23:06:59

标签: c# .net automatic-properties

注意:这是在我开始使用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;组;阻止,因此甚至可以保存更多代码。

那么,我在这里错过了什么?为什么有人真的想要使用自动属性?

18 个答案:

答案 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)

使用字段而不是属性的三大缺点是:

  1. 您不能将数据绑定到字段,而您可以使用属性
  2. 如果您开始使用字段,则以后(轻松)将其更改为属性
  3. 您可以将某些属性添加到无法添加到字段的属性

答案 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)

我一直使用自动属性。在C#3之前,我不会被所有打字困扰,而只是使用了公共变量。

我唯一想念的是能够做到这一点:

public string Name = "DefaultName";

您必须将默认值转换为具有属性的构造函数。乏味的: - (

答案 9 :(得分:5)

我认为任何直观的构造都会减少代码行是一个很大的优势。

这些特性使Ruby这样的语言如此强大(动态特性,也有助于减少多余的代码)。

Ruby一直都这样:

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter

答案 10 :(得分:2)

这很简单,它很简短,如果你想在属性内部的某个地方创建一个真正的实现,它不会破坏你的类型的外部接口。

就这么简单。

答案 11 :(得分:2)

我与他们唯一的问题是他们走得不够远。添加自动属性的编译器的同一版本,添加了部分方法。为什么他们没有将两者结合在一起超出了我的范围。一个简单的“部分On< PropertyName> Changed”会使这些事情变得非常有用。

答案 12 :(得分:1)

这里要注意的一点是,根据我的理解,这是C#3.0端的只是语法糖,这意味着编译器生成的IL是相同的。我同意避免黑魔法,但同样的,相同的东西通常是一件好事。

答案 13 :(得分:1)

在我看来,您应该始终使用自动属性而不是公共字段。那就是说,这是妥协:

使用您用于属性的命名约定,从internal字段开始。当你第一次

  • 需要从其装配外部访问该字段,或
  • 需要将逻辑附加到getter / setter

这样做:

  1. 重命名字段
  2. 私有化
  3. 添加公共财产
  4. 您的客户端代码无需更改。

    但是,有一天,您的系统将会增长,您将把它分解为单独的程序集和多个解决方案。当发生这种情况时,任何暴露的字段都会回来困扰你,因为正如杰夫所说,changing a public field to a public property is a breaking API change

答案 14 :(得分:0)

@Domenic:我不明白..你不能用自动属性做这个吗?:

public string Title { get; }

public string Title { get; private set; }

这是你指的是什么?

答案 15 :(得分:0)

我对自动属性的最大抱怨是它们旨在节省时间,但我经常发现我必须在以后将它们扩展为完整的属性。

VS2008缺少的是爆炸自动属性重构。

我们拥有封装字段重构这一事实使我更快地使用公共字段。

答案 16 :(得分:0)

我使用CodeRush,它比自动属性更快。

要做到这一点:

 private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

总共需要八次击键。

答案 17 :(得分:0)

使用代码片段,同名的自动属性总共会有七次击键;)