Lazy dictionary properties in C#

Go To StackoverFlow.com

8

I have a class with a property that's a Dictionary:

public class Entity 
{
        public Dictionary<string, string> Name { get; set; }
}

I would like switch this property to use lazy initializtion. I tried the following:

public class Entity 
{
        private Lazy<Dictionary<string, string>> name = new Lazy<Dictionary<string, string>>(() => new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase));
        public Dictionary<string, string> Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }
}

This is of course an error, as Name and name have different types. For the life of me though, I can't figure out how to specify this correctly. All I really want is to have Name remain null until I access it, then create it on the first read or write.

2012-04-03 23:31
by Justin R.


10

You can use the initialization with Lazy, but what you want is pretty simple and you could simply do this

    private Dictionary<string, string> _name;
    public Dictionary<string, string> Name
    {
        get
        {
            if(_name == null)
                _name = new Dictionary<string, string>();
            return _name;
        }
        set
        {
            _name = value;
        }
    }

EDIT: Note that this approach will have some thread safety issues. Check if this can be a problem for you.

2012-04-03 23:34
by dee-see
You have a race condition in there - LukeH 2012-04-03 23:40
Yeah added I added a note about this probably as you were typing your comment. ; - dee-see 2012-04-03 23:41
D'oh, looks like I was using my complicator's gloves. This is what happens when I become enamored with a cool feature. Thanks, I'll mark this as the answer as soon SO lets me. Now, because I have a bunch of these, I just need to make some sort of factory for them - Justin R. 2012-04-03 23:42
or just get { return _name ?? (_name = new Dictionary<string, string>()); }drch 2012-04-04 02:03
Yeah that's a nice one liner but some people won't like to assign in the return. I guess you lose some readability - dee-see 2012-04-21 21:42


7

name.Value is read-only. Try this:

public class Entity 
{
    private Lazy<Dictionary<string, string>> name = 
        new Lazy<Dictionary<string, string>>(
            () => new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase));

    public Dictionary<string, string> Name
    {
        get
        {
            return name.Value;
        }
    }
}
2012-04-03 23:41
by bouvierr
It's read-write - Justin R. 2012-04-03 23:46
The Lazy.Value property is read-only: http://msdn.microsoft.com/en-us/library/dd642177.aspx If you mean that your requirement is for a read-write property, then the solution above is incomplete - bouvierr 2012-04-04 00:01