C#属性:它们是如何实例化的?

时间:2009-06-17 05:38:00

标签: .net properties compilation

这可能是一个非常简单的问题,但我正在尝试理解编译的一些内部工作原理。

非常简单地说,想象一下任意对象被实例化。然后在堆上分配此对象。该对象具有PointF类型的属性(值类型),带有get和set方法。

想象一下get和set方法包含一些用于完成工作的计算。这个代码的实例化方式和位置(堆栈/堆)以及何时实现?


这是这个问题的背景:

我正在为对象编写get和set方法,并且需要非常频繁地访问这些方法。 get和set代码本身相当庞大,所以我担心在最糟糕的情况下,这些方法会被实例化为一个对象或一个值类型,每个访问属性的内部代码都是如此。另一方面,代码可能在创建主对象时被实例化,并且简单地告诉CPU将jmp指向属性代码start。无论如何,这是我想澄清的。

6 个答案:

答案 0 :(得分:8)

方法(或属性)未实例化。你似乎在思考我曾经做过的事情 - 创建一个类的实例不仅为数据分配空间,而且为代码分配空间。事实并非如此。

即使在C ++中,它的工作方式是分配数据,以及指向函数指针数组的指针 - 虚函数表或vtable。 vtable中的条目将指向虚方法。非虚方法不需要在vtable中输入。

在任何一种情况下,只有一个代码副本,无论实例化了多少个对象。

答案 1 :(得分:3)

我这里没有CLR via C#的副本,但是属性的getter和setter只是具有特殊装饰的类的方法。 Jeffery Richter的优秀书籍将包含所有细节。

答案 2 :(得分:3)

可执行代码既不在堆栈上也不在堆上分配,它在需要时由JIT'er编译,并且相应的内存被留出一次。也就是说,你担心什么本质上是一个非问题。另外,不要试图再次猜测垃圾收集器在内存分配方面做了什么 - 它可以让你不必担心。

答案 3 :(得分:1)

他们与方法没什么不同。

答案 4 :(得分:1)

我不确定你实例化的意思,但是如果你担心getter的运行时间,你可以考虑缓存响应。但是,我不会这样做,直到我确认吸气剂确实损害了你的程序的性能。

答案 5 :(得分:-1)

根据this page on MSDN属性和方法确实存在一些本质区别。特别是在返回数组时,属性会在返回数组之前执行整个数组的浅表副本,因此,您需要使用自定义函数。

但是,正如我上面所解释的,如果我以任何方式使用属性而不是函数,我想知道程序是否会受到性能损失。总的来说,我确实发现,由于某些无法解释的原因,属性平均比函数慢约5%。这可能是因为属性拥有一系列“隐形”对象,例如属性描述符等。除此之外,实现似乎非常相似。

相关问题