Short version:
Unless you are doing something interesting in your accessors, then for “full” .NET on classes, it makes no difference. Use automatically-implemented properties, and “commit”.
Much ado about nothing:
Previously, I discussed ways of modelling a general-purpose property accessor, and looked at existing APIs. So what next? I’m rather bored of conversations like this on forums:
OP: My flooble-gunger application uses public fields to hold the flipple-count, but I’m getting problem…
Me: back up there…. why does it use public fields?
OP: For optimisation, obviously!
But is there anything “obvious” here? I don’t think this is news to most people, but public fields are not generally a good idea – it breaks encapsulation, is (despite belief otherwise) a breaking change (and sometimes build-breaking) to swap for properties, doesn’t work with data-binding, can’t participate in polymorphism or interface impementation, etc.
With regards to any performance difference, you would expect that in most “regular” code, member-access does not represent the overhead. We would hope that the only times when member-access might be truly interesting is (like for me) if you are writing serialization / materialization code. Still, let’s plough on with this scenario, and check things out.
In particular, for simple properties (for example, C# 3.0 “automatically implemented properties”) our expectation is that they will commonly be “inlined” by the JIT. The big caveat here (where I might forgive you) is Compact Framework (for example XNA on XBox 360), which has a much weaker JIT.
So as before; let’s test it. Another very simple test rig, I want to compare (each in a loop):
- Direct property access on an object
- Direct field access on an object
- A wrapper (as before) that talks to a public property
- A wrapper (as before) that talks to a private property
- (automatically implemented properties vs manual properties)
- A wrapper (as before) that talks to a public field
- A wrapper (as before) that talks to a private field
To achieve the private tests, I’ve created the wrapper implementation as a nested type of the object I’m testing. Oddly enough, there were some oddities that popped up, but I’ll discuss those next time; this post has been long enough, so here’s the very uninteresting result (sorry for the anti-climax):
Implementation | Get performance | Set performance | |
|
Both direct and via abstraction, the cost is identical for fields and properties. Quite simply – don’t stress over it.