C # 3.0自动属性ーー是否有用?

注意: 这是在我开始使用 C # 时发布的。有了2014年的知识,我可以确切地说,自动属性是 C # 语言中发生过的最好的事情之一。

我使用一个私有和一个公共字段在 C # 中创建我的属性:

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

现在,有了 .NET3.0,我们就有了自动属性:

public string Title { get; set; }

我知道这更多是一个哲学/主观的问题,但是除了为每个字段保存5行代码之外,还有什么理由使用这些自动属性吗?我个人的抱怨是那些房子对我隐瞒了一些事情,而我不是黑魔法的狂热粉丝。

事实上,隐藏的私有字段甚至不会在调试器中显示出来,考虑到 get/set 函数什么都不做,这样做是可以的。但是,当我想实现一些 getter/setter 逻辑时,无论如何都必须使用私有/公共对。

我看到了这样做的好处: 我节省了大量的代码(一行对六行) ,而且以后不会失去更改 getter/setter 逻辑的能力,但是我已经可以通过简单地声明一个公共字段“ Public string Title”来做到这一点,而不需要{ get; set; }块,因此甚至可以节省更多的代码。

那么,我到底漏掉了什么呢? 为什么会有人真的想要使用自动属性呢?

49309 次浏览

我个人很喜欢汽车产业。保存代码行有什么问题吗?如果您想在 getter 或 setter 中进行操作,稍后将它们转换为普通属性没有问题。

正如您所说的,您可以使用字段,如果您想在以后向它们添加逻辑,您可以将它们转换为属性。但是这可能会给反射的使用带来问题(可能还有其他地方?).

此外,这些属性还允许您为 getter 和 setter 设置不同的访问级别,而您无法对字段这样做。

我想这和 var 关键字是一样的,只是个人偏好的问题。

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

  1. 不能绑定到字段,但可以绑定到属性
  2. 如果您开始使用一个字段,以后就不能(容易地)将它们更改为一个属性
  3. 有一些属性可以添加到属性中,但不能添加到字段中

我们在 Stack Overflow 中一直在使用它们。

您也可能对 属性与公共变量的讨论感兴趣。恕我直言,这真的是一个反应,为了这个目的,这是伟大的。

我一直在使用自动属性。在 C # 3之前,我不愿意为所有的类型操心,而只是使用公共变量。

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

public string Name = "DefaultName";

您必须使用 properties 将默认值转换为构造函数

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

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

露比一直有这个:

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter

我唯一的问题就是他们做的还不够。同一版本的编译器添加了自动属性,添加了部分方法。我不明白他们为什么不把这两者结合起来。一个简单的“ part On < PropertyName > Changed”就可以让这些东西变得非常有用。

是的,它做 只是保存代码。如果你有很多这样的书,读起来就容易多了。它们编写起来更快,维护起来也更容易。保存代码始终是一个很好的目标。

您可以设置不同的范围:

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"; }

在具有大量成员的不可变类中,这可以节省大量多余的代码。

这里需要注意的一点是,据我所知,这是 C # 3.0末端的 只是语法代码,这意味着编译器生成的 IL 是相同的。我同意避免使用黑魔法,但尽管如此,对同一件事少说几句台词通常是件好事。

在我看来,你应该总是使用自动属性,而不是公共字段。这就是说,这里有一个折衷方案:

首先,使用属性的变数命名原则设置一个 内部字段

  • 需要从其程序集外部访问字段,或者
  • 需要将逻辑附加到 getter/setter

这样做:

  1. 重命名字段
  2. 私下谈
  3. 增加公共财产

您的客户端代码不需要更改。

但是,总有一天,您的系统会发展壮大,您将把它分解成单独的程序集和多个解决方案。当这种情况发生时,任何暴露的字段都将回来困扰您,因为正如 Jeff 所提到的,将公共字段更改为公共属性是一个破坏性的 API 更改

自动属性和 C # 中的其他任何东西一样都是一种黑魔法。一旦你从编译到 IL 而不是扩展到一个普通的 C # 属性的角度来考虑这个问题,你就会发现它比很多其他语言结构都要简单。

我用的是 CodeRush 比自动属性快多了。

要做到这一点:

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

总共需要八次击键。

有一件事似乎没有人提到,那就是自动属性对于不可变对象(通常是不可变的结构)是如何不幸地没有用处的。因为你真的应该这么做:

private readonly string title;
public string Title
{
get { return this.title; }
}

(其中字段通过传递的参数在构造函数中初始化,然后只读。)

因此,与简单的 get/private set自动属性相比,它具有优势。

@ Domenic: 我不明白. . 你不能用汽车特性做这个吗:

public string Title { get; }

或者

public string Title { get; private set; }

你是指这个吗?

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

就这么简单。

来自比雅尼·斯特劳斯特鲁普 C + + 的创造者:

我特别不喜欢带有大量 get 和 set 函数的类。这通常意味着它从一开始就不应该是一个类。这只是个数据结构。如果它真的是一个数据结构,那就让它成为一个数据结构。

你知道吗?他说得对。只是简单地在 get 和 set 中包装私有字段而不在 get/set 中实际执行任何操作的情况有多少,这仅仅是因为这是“面向对象”的事情。这是微软针对这个问题的解决方案; 它们基本上是您可以绑定到的公共字段。

我对自动属性最大的抱怨是,它们的设计是为了节省时间,但我经常发现,我不得不在以后将它们扩展成完整的属性。

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

事实上,我们有一个 封装字段重构器,使我工作的方式更快,只使用公共字段。

我总是创建属性而不是公共字段,因为可以在接口定义中使用属性,但不能在接口定义中使用公共字段。