views:

153

answers:

1

(except for proxy setup!)

I spent some time writing a question here regarding a better pattern for a problem I had - of a class that performed some conditional initialization on almost every property getter, since the initialization in the base class relied on data from the inheriting classes that wasn't available on construction.

While writing the question I came to the conclusion it would be better practice to initialize on inheritor construction. This would require every inheriting class to call the parents initialization method, but I think it's better, because:

  1. I don't have to remember to initialize in the base class on every new property getter/setter.
  2. I don't accidentally trigger the initialization while debugging (see my question here)

If you ever had code that changes state in a property getter, do you think it's absolutely justified? Can you give an example for such a case? (Or even describe the pattern?)

I could only think of proxy access, where you don't want to perform initialization until property access...


Somebody suggested that I initialize using a factory/static method - that's actually a good idea (when the construction is simple, a bit harder when it's not uniform across inheriting classes), but the answer was deleted before I had a chance to submit my reply. too bad.

+3  A: 

Lazy caching. Where you dont load the data from the database until the property is accessed. (Not sure if this is what you mean by proxy access).

However, I wouldnt really consider this to be logically changing the state of the object as the behaviour of the class remains the same before and after access. The data is implicitly there at all times. The logical state remains unchanged.

I would never change the logical state of a class through a getter as it is counter intuitive and logically incorrect. You do risk all sorts of unintended consequences..

You could do something like the following :

    public class baseone
    {
     private baseone ()
     {
     }

     public baseone ( string huh )
     {
                initialise(huh);
     }

            protected abstract initialise(string stuff); 
    }


    public class niceone : baseone
    {
     public niceone (string param)
      : base(param)
     {

     }

            protected override initialise(string stuff)
            {
               // do stuff..
            }
    }

Making the default constructor of the base class private ensures that the required parameters must be passed to initialise the class.

Mongus Pong
lazy caching is (usually/often) done via proxy, so I also mean that. I agree with what you say about changing the state vs. changing the behavior. the proposed workaround isn't always applicable though, since the initialization may rely on virtual methods... and performing everything before calling the base class constructor may result in more code duplication.
Yonatan Karni
Have changed the sample a bit.. initialise can be a virtual method. The base class constructor is going to be the first method that gets called when the class is constructed. The derived constructor is called after that..I think thats what you mean.. (still trying to wake up...)
Mongus Pong
wouldn't you prefer to avoid virtual method calls in the constructor?
Yonatan Karni
For sure, you do have to be careful.. This thread goes into a bit more detail : http://stackoverflow.com/questions/448258/calling-virtual-method-in-base-class-constructor.(I have just learnt something myself here!)
Mongus Pong