读/写操作中的属性与支持字段之间是否存在性能差异?

时间:2010-07-02 15:39:03

标签: .net performance properties backing-field

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

我在某种程度上明白,这将是一种更为普遍的执行方式,但我发现我并没有任何证据支持这一想法。

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

4 个答案:

答案 0 :(得分:3)

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

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

属性有一些好处,即使它们只是获取/设置封面:

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

顺便说一句,虽然回顾这些事情的微小性能特征很有意思 - 在生产代码中应用这种类型的优化(好吧,在这种情况下没有一个),可能接受过早优化的旗帜。

答案 1 :(得分:3)

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

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

由于C#编译器从属性声明中创建了单独的getter和setter方法,因此显然可以相互独立地对待它们。基于上面的规则,我会说大多数时候属性访问器都是内联的。我认为关于方法必须是非虚拟的规则将是经常发生的非常重要的showstoppers之一。

答案 2 :(得分:1)

性能不应该有差异。如果使用Reflector查看代码的反汇编,它会以最简单的方式自动为您创建支持字段。它实际上只是编译器为您提供的语法糖,使您的生活更轻松。

答案 3 :(得分:1)

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