CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Greg Young [MVP]


Framework Design Guidelines: Property or Method

I have a proposed addition to “Framework Design Guidelines” based upon a situation that came up a few days ago. I believe the situation is already covered implicitly but there seems to be some contention on that point so perhaps some clarification would help us write better code.

The situation has to deal with the choice between a method and a property. The rules currently state

CONSIDER using a property if the member represents a logical attribute of the type

DO use a method rather than a property in the following situations

·         The operation is orders of magnitude slower than a field access would be.

Given in the framework design guidelines the order of magnitude rule is referring more to items such as those that access network resources.

The case which needs to be clarified is when you are dealing with a property that may also be used as a looping termination condition. If it is done as a property but is not a simple field access the client has no way to know whether or not they need to manually hoist the loop. As an example consider the following.

        static void Example() {

            for (int i = 0; i < SomeObject.Size; i++) {

                //dosomething

            }

        }

 

 

As we learned in An in depth look at for loops if Size is a simple field access that gets inlined the access will automatically be hoisted. If however it is not a simple field access that gets inlined it will be called on every iteration of the loop.

From a client developer point of view we have no way of knowing how we should structure our loop without knowing the internal implementation of SomeObject, particularly how the Size property is implemented. If the property is not a simple field access that will be inlined we need to know to hoist it manually as in the following example.

        static void Example() {

            int count = SomeObject.Size;

            for (int i = 0; i < count; i++) {

                //dosomething

            }

        }

 

Or more appropriately..

        static void Example() {

            for (int i = 0, count=SomeObject.Size; i < count; i++) {

                //dosomething

            }

        }

 

Given one could make the argument to always use these forms in order to work around the question but this code certainly seems to be a bit more cryptic than the first version. I would also wager it quite likely that a Jr. developer could fall into the mistake of undoing this code (or writing it as the first version without realizing the performance impact). There are also numerous resources telling you specifically not to hoist property accesses due to the optimization that occurs when the property can be inlined.

Of course the real question is where does this actually happen … I personally got caught by the Image object in the framework. Height and Width will in turn pinvoke to native code eliminating the possibility of the JIT automatically hoisting the call. As such looping with height or width as termination conditions will cause a pinvoke on every iteration of your loop.

In order to help alleviate this I propose to add a point of guidance specific to looping stop conditions. If it is a simple field access, make it a property. If it is not a simple field access make it a method. It is much clearer from a client perspective that a method incurs the further overhead and should therefore be hoisted manually.



Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!

Our Sponsors

Free Tech Publications