+13  A: 

Your method is flawed. To take this approach you need to make backingField a ref parameter.

private static T GetProperty<T>(ref T backingField, Func<T> factory)

Then on GetProperty, pass ref _ImagXpress or ref _PdfXpress.

The way you're doing it now just assigns a new value to the parameter, not to the actual backing field.

Adam Robinson
+1, although ref variables are generally a code smell. Since it's private, at least the ref ugliness is fully encapsulated.
Michael Meadows
What I do not get it, when I pass a class variable `_PdfXpress` to `GetProperty`, even thought I am passing by value, since `_PdfXpress` is a reference type, shouldn't `_PdfXpress` should be created within `GetProperty`?Why should I explicitly say `ref`?
Sung Meister
Agreed; not the approach I'd take either, but it fits his model.
Adam Robinson
You are passing by value, which means that if you change the VALUE (meaning what the reference variable actually points to), you only update your local copy. You have to pass by REFERENCE to make changes to the VALUE propagate back.
Adam Robinson
a ref parameter is functionally similar to a double pointer, which allows you to substitute the entire object reference. A value parameter is functionally similar to a single pointer, reassigning the parameter (backingField = factory()) will only replace it in the scope of the method. You can manipulate state of a value parameter, but not its reference to the object on the heap.
Michael Meadows
@Adam: It looks like I have to brush up on passing a reference object by value a bit. Thank you for your guidance.
Sung Meister
Object references in C# are NOT pointers. They're explicitly NOT pointers, and there's a big difference. Adding ref to the argument makes it act more like a pointer, which is what you're wanting in this situation.
dustyburwell
Jon Skeet can answer this much better than I can:http://www.yoda.arachsys.com/csharp/parameters.html
Michael Meadows
@Miachael Meadows: Reading Jon's article on following sections, "Value parameters" and "Reference parameters" cleared up my confusion. Basically what I did wrong was that, I was setting the copy of reference of class variables to another instance so the original reference would never be assigned to a new address. This is such an eye-opener.
Sung Meister
+5  A: 

Your approach is flawed. You're fields will never be set to anything. the backingField argument is being set in the GetProperty<T> method, but this does not update the field you're passing in. You'll want to pass in that argument with the ref keyword attached to it like this:

private static T GetProperty<T>(ref T backingField, Func<T> factory)
dustyburwell
+1  A: 

To propose a different solution:

I'd say that you're not saving a whole lot by encapsulating that logic into a separate method. You're increasing your complexity without much gain. I'd suggest doing it this way:

protected PdfXpress PdfXpress
{
    get
    {
        if (_PdfXpress == null)
            _PdfXpress = PdfXpressSupport.Create();

        return _PdfXpress;
    }
}

protected ImagXpress ImagXpress
{
    get
    {
        if (_ImagXpress == null)
            _ImagXpress = IMagXpressSupport.Create();

        return _ImagXpress;
    }
}

You're adding a few lines, but decreasing complexity considerably.

dustyburwell
That was my initial implementation; But I would have to add more properties so i ended up refactoring a method to encapsulate "null" check.
Sung Meister
dance: There is such a thing as over-engineering :) I would greatly favor this approach, as it's much clearer what's going on.
Adam Robinson
@Adam: I am now beginning to see that, I tend to refactor/over-engineer too much...
Sung Meister
+3  A: 

As I stated in comments on another answer, the need for a ref parameter is a code smell. First of all, if you're doing this in a method, you're breaking the single responsibility principle, but more importantly, the code is only reusable within your inheritance heirarchy.

There's a pattern to be derived here:

public class LazyInit<T>
    where T : class
{
    private readonly Func<T> _creationMethod;
    private readonly object syncRoot;
    private T _instance;

    [DebuggerHidden]
    private LazyInit()
    {
        syncRoot = new object();
    }

    [DebuggerHidden]
    public LazyInit(Func<T> creationMethod)
        : this()
    {
        _creationMethod = creationMethod;
    }

    public T Instance
    {
        [DebuggerHidden]
        get
        {
            lock (syncRoot)
            {
                if (_instance == null)
                    _instance = _creationMethod();
                return _instance;
            }
        }
    }

    public static LazyInit<T> Create<U>() where U : class, T, new()
    {
        return new LazyInit<T>(() => new U());
    }

    [DebuggerHidden]
    public static implicit operator LazyInit<T>(Func<T> function)
    {
        return new LazyInit<T>(function);
    }
}

This allows you to do this:

public class Foo
{
    private readonly LazyInit<Bar> _bar1 = LazyInit<Bar>.Create<Bar>();
    private readonly LazyInit<Bar> _bar2 = new LazyInit<Bar>(() => new Bar("foo"));

    public Bar Bar1
    {
        get { return _bar1.Instance; }
    }

    public Bar Bar2
    {
        get { return _bar2.Instance; }
    }
}
Michael Meadows
Seems a bit over-engineered, but should work and is certainly a creative solution!
Adam Robinson
over-engineered for this particular solution, but it provides a thread-safe (relatively) lazy initialization method that can reused everywhere. It's production code I use that is a result of several iterations of refactoring lazy initialization code.
Michael Meadows
@Michael Meadows: Wow, I think i could integrate LazyInit into my code. Thank you for providing difference perspective on solving the issue. I haven't thought about creating an entirely new class for lazy loading.
Sung Meister
I only have one suggestion. Suppose the expensive operation you are deferring actually results in a null? It will keep getting evaluated on subsequent calls. I took your class and added a private boolean "initialized" variable rather than rely on comparing _instance against null. It's now standing in for the .Net v4.0 Lazy<T> class in my v3.5 project. Thanks.
Mel