C# 为什么属性执行比字段或方法执行慢?
杰夫·里克特在第10章“财产”中写道: 属性方法可能需要很长时间才能执行;现场访问始终有效 立即完成。使用属性的一个常见原因是 执行线程同步,可以永久停止线程, 因此,如果线程 需要同步。在这种情况下,首选一种方法。 此外,如果可以远程访问您的类(例如,您的类 派生自System.MarshalByRefObject),调用该属性 方法将非常慢,因此,方法优先于 财产。在我看来,类派生自MarshallByRefObject 不应使用属性 即使属性被定义为只返回私有字段,也是这样吗?为什么在同步中首选方法?为什么在MarshalByRefObject场景中首选方法C# 为什么属性执行比字段或方法执行慢?,c#,.net,performance,synchronization,clr,C#,.net,Performance,Synchronization,Clr,杰夫·里克特在第10章“财产”中写道: 属性方法可能需要很长时间才能执行;现场访问始终有效 立即完成。使用属性的一个常见原因是 执行线程同步,可以永久停止线程, 因此,如果线程 需要同步。在这种情况下,首选一种方法。 此外,如果可以远程访问您的类(例如,您的类 派生自System.MarshalByRefObject),调用该属性 方法将非常慢,因此,方法优先于 财产。在我看来,类派生自MarshallByRefObject 不应使用属性 即使属性被定义为只返回私有字段,也是这样吗?为什么在同步
为了澄清我的问题:
Jeff似乎在做一个笼统的陈述,即属性是不可取的,在这两种情况下方法更可取。正如Joe White指出的,属性可以有任意代码。但是方法可以运行相同的任意代码。这是我遇到困难的部分。在同步或封送处理中,使用方法比使用属性(使用相同的代码)更有优势吗?还是他只是在语言约定方面有问题?我想他是在强调,因为属性可以运行任意代码,所以调用代码不应该假设它会立即完成 如果属性所做的只是返回一个字段,那么它的方法体实际上将由JIT编译器内联,并且它将与字段访问一样快。所以这并不是说房地产在某种程度上变慢了;这是因为它们是黑匣子。如果您不知道一个属性是如何实现的,那么就不能假设它会很快返回 (也就是说,创建一个慢速属性显然违反了,特别是这一条:“如果操作比字段集慢几个数量级,请使用方法而不是属性”。)
至于他建议用方法来代替,我一点也不明白。属性是方法:属性getter是一个方法(通常命名为
get\u PropertyName
),属性setter是一个方法(set\u PropertyName
),读取属性的代码被编译为对get\u PropertyName
进行方法调用的代码。没有什么特别的东西会使属性比方法慢。我认为关键是属性访问看起来像字段访问,所以人们不会期望有任何异常
如果您有一个可能需要很长时间的属性,您应该将其重写为一个方法。这不会使您的代码执行得更好,但更清楚的是,这可能需要很长时间
就性能而言,属性访问和方法调用之间没有区别。实际上,属性访问只是一个方法调用。一个方法并不比一个属性快,但是一个方法不应该比一个属性快。因此,最好使用该方法来明确这可能需要一些时间(因为在本例中是线程同步)
字段根本不“执行”。访问字段就是直接访问内存。Jeff的观点是,“GetBlah”方法调用向读卡器传达“这可能很慢”,而“Blah”属性传达“这几乎肯定很快”。所以,如果你想让事情变得缓慢,那就把它作为一种方法。我并不完全同意这一建议——例如,我经常制作一些不太可能出现最坏情况但摊销后表现优异的房产。但杰夫的建议绝对是一个很好的起点;一旦你知道你在做什么,就要偏离它。访问实例字段就是间接地访问内存,因为首先你必须在内存中找到接收者。@Eric:是的,当然,我的意思是你在访问内存,而不是执行代码。嗯。。他明确表示“调用属性方法将非常缓慢,因此,方法比属性更可取”。所以这不仅仅是外表的问题。。至少根据杰夫的说法,给酒店打电话会很慢,而且人们并不期望酒店会很慢。调用一个方法的速度同样慢,但人们期望某些方法会很慢。