0

I was trying to find a concrete example online but I couldn't find one that also used one of the class' other attributes.

So, can this be done more succinctly with a Lazy<T> object?

    public string BrandAbbreviation { get; set; }

    private bool _brandPopulated = false;
    private CommonBrand _brand;
    public CommonBrand Brand
    {
        get
        {
            if (!_brandPopulated){
                _brand = new CommonBrand(BrandAbbreviation);
                _brandPopulated = true;
            }

            return _brand;
        }
    }
  • You can use the constructor of Lazy<T> which accepts an initialization func<T>. msdn.microsoft.com/en-us/library/dd642329(v=vs.110).aspx – Rotem May 17 '16 at 14:28
  • You're not setting _brandPopulated to true anywhere. Is that deliberate? – Ben Aaronson May 17 '16 at 15:03
  • Wasn't worried too much about that as it was just an example - I did update it just in case someone else tries to use the same approach and needs the boolean for something. Thanks – user107775 May 17 '16 at 15:33
  • @Rotem The constructor won't let me use other attributes in the class - that's the same issue I had when trying to use MainMa's suggestion. I was hoping there was a way around this. – user107775 May 17 '16 at 15:34
2

Removing a field

Even without Lazy<T>, you may shorten the code by removing the redundant variable:

public string BrandAbbreviation { get; set; }

private CommonBrand _brand;

public CommonBrand Brand
{
    get
    {
        if (!this._brand == null)
        {
            this._brand = new CommonBrand(this.BrandAbbreviation);
        }

        return this._brand;
    }
}

Removing _brandPopulated has not only the benefit of removing a few LOCs, but also makes the code clearer. By having a separate field which flags whether _brand is set, you could potentially have situations you don't handle in your code (and which are not obvious to handle right):

  • _brandPopulated is false, but _brand is initialized to a value. Should we forget about the previous value? Should we keep it?

  • _brandPopulated is true, but _brand is null. How do you handle that? Do you check for null after checking for _brandPopulated? Or maybe you don't, and risk encountering an ugly NullReferenceException?

Introducing (or not) Lazy<T>

You can indeed use Lazy<T>, which makes it possible to make the code even shorter:

public string BrandAbbreviation { get; set; }

private readonly Lazy<CommonBrand> _brand;

public ClassName() // Replace by the name of the actual class.
{
    this._brand = new Lazy<CommonBrand>(() => new CommonBrand(this.BrandAbbreviation));
}

public CommonBrand Brand
{
    get
    {
        return this._brand.Value;
    }
}
  • I tried doing what you suggested but got some build errors. That's what I ran into before posting this as well ... apparently, you can't use other attributes from the instance itself in Lazy instantiations. I was hoping there was something I was missing but maybe not.... – user107775 May 17 '16 at 15:27
  • Errors from the build: Cannot convert lambda expression to type 'bool' because it is not a delegate type Keyword 'this' is not available in the current context When I switch it over to your initial suggestion, it builds fine. – user107775 May 17 '16 at 15:30
  • @user107775: I see. No, it has nothing to do with Lazy<T>, but with the fact that I did the initialization directly when creating the field: the initialization code should be moved to the constructor. I edited the answer. – Arseni Mourzenko May 17 '16 at 15:32
  • Your reasoning about the bool flag is incomplete. What about the case where null is a valid value? I'd also argue that by making null a magic value you're removing clarity. – MetaFight May 17 '16 at 15:41
  • 1
    @user107775 what's passed to the Lazy<T> constructor is a generator function. It does not build the CommonBrand object until executed, which happens the first time you reference Lazy<T>.Value. – Dan Lyons May 17 '16 at 18:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.