2

当在一个类中处理它自己的字段和属性时,我通常只在它执行某些功能时使用该属性(例如限制值或验证或其他)。否则我更喜欢直接读/写支持字段。

我不知何故想到这将是一种更普遍的执行方式,但我突然想到我并没有任何证据支持这个想法。

除了惯例或口味之外,一种方法和另一种方法之间是否存在实际的性能因素?

4

4 回答 4

3

如果属性是直接获取/设置它的编译器 - 换句话说,编译器将直接使用属性或字段转换为相同的东西 - 所以没有性能差异。

但是,get/sets 可以包含他们想要的任何逻辑,因此可能会很昂贵 - 但是,指南通常建议保持它们轻巧。

属性有一些好处,即使它们只是 get/set 覆盖:

  • 数据绑定只能看到属性,不能看到字段。
  • 它与封装的概念保持一致。
  • 您可以强制执行只读或只写语义。
  • 您可以将属性单独应用于基础字段(在序列化场景中很有用)。

顺便说一句,尽管回顾这些东西的微小性能特征很有趣——在生产代码中应用这种类型的优化(好吧,在这种情况下没有)可能会受到过早优化的影响。

于 2010-07-02T15:41:14.400 回答
3

这真的取决于。从技术上讲,它可能会更慢,但即使在那些情况下,它也几乎是不可察觉的。以下是从这里获取的方法内联如何工作的规则。

  • 大于 32 字节 IL 的方法将不会被内联。
  • 虚函数没有内联。
  • 具有复杂流控制的方法不会被内联。复杂流控制是除 if/then/else 之外的任何流控制;在这种情况下,切换或同时。
  • 包含异常处理块的方法不是内联的,尽管抛出异常的方法仍然是内联的候选方法。
  • 如果方法的任何形式参数是结构,则该方法将不会被内联。

由于 C# 编译器从属性声明中创建了单独的 getter 和 setter 方法,因此它们显然会相互独立地处理。根据上面的规则,我想说大多数时候属性访问器都是内联的。我认为关于方法必须是非虚拟的规则将是经常发生的不平凡的阻碍之一。

于 2010-07-02T15:51:41.240 回答
1

性能上应该没有区别。如果你使用Reflector来查看代码的反汇编,它会以最简单的方式自动为你创建 backing field。它实际上只是您的编译器为您提供的让生活更轻松的语法糖。

于 2010-07-02T15:41:19.953 回答
1

如果类或结构公开了结构类型的可变字段,则可以访问该结构的各个字段而无需复制整个内容。相比之下,如果它公开了一个属性(可变或不可变)或“只读”字段,那么访问结构的任何部分都会导致系统复制整个结构,然后访问副本。此外,消费者代码可以方便有效地修改暴露的结构字段的字段,而无需任何多余的复制操作。相比之下,如果一个结构作为一个属性公开,修改它的任何部分都需要消费者将它复制到一个临时变量,进行更改,然后将其存储回来,一系列步骤可能会导致整个结构抄四次(供方和消费者阅读时各抄一次,

于 2012-07-31T20:21:02.493 回答