9

I have a property:

public Dictionary<string, string> MyProp { get; set; }

When I invoke that property to add an item, I get a NullReferenceException.

How would I do the null check in the property itself so it gives me a new one if it is null? While keeping in the auto-property pattern.

8 Answers 8

7

Without an explicit private variable the only other way would be to add some code to the constructor of the class:

MyProp = new Dictionary<string,string>();

As nza points out in their answer from C# 6.0 onwards you can do this:

public Dictionary<string, string> MyProp { get; set; } = new Dictionary<string, string>();

If you use this pattern then you'll get initialised properties whenever you add a new one, without having to add the initialisation in the class's constructor.

Sign up to request clarification or add additional context in comments.

1 Comment

OK I went with this one, it's the cleanest.
6

You can initialize it in your constructor:

public MyClass()
{
  MyProp = new Dictionary<string, string>();
}

Comments

4

For other people falling over this old question, there is a new feature in C# 6.0.

In C# 6.0, you can also initialize that property to some constant value in the same statement, like this:

public Dictionary<string, string> MyProp { get; set; } = new Dictionary<string, string>();

1 Comment

I would remove the setter since you probably wouldn't want to recreate the dictionary object. Declaring just the getter is valid.
3

I don't think you will want a setter, since that will always make a new dictionary, as others have pointed out by calling the setter in the constructor. A better approach is:

public Dictionary<string, string> MyProp { get; internal set; }
public MyClass() { MyProp = new Dictionary<string, string>(); }

Here you've used the internal setter to create the dictionary. After this, if you want to add an element to the dictionary, you would do this in your code:

InstanceOfMyClass.MyProp.Add(blah, blah);

where you use the getter to get the dictionary object, then do an Add to add a new item. You can't call the setter from your code and accidentally wipe out the dictionary, because it will look readonly to anything outside of MyClass.

2 Comments

why internal rather than private, out of interest?
Good point - it depends on the use case. internal would give any other class within the same assembly access to the setter. private would probably make more sense.
2

Initialize it in the constructor

public MyClass(){  dictionary = new
 Dictionary<string,string>() 
}

Comments

1

You will have to use an explicit backing field, you cannot change the getter or setter for auto-properties.

Comments

1

There's an attribute class named DefaultValueAttribute that allows you to specify the desired default value of a member, however, it doesn't automatically set the member to the value specified; hope is not lost, though, as you can use reflection to retrieve this value at runtime and apply it, as posed in this corner of the internet:

static public void ApplyDefaultValues(object self)
{
    foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(self))
    {
        DefaultValueAttribute attr = prop.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
        if (attr == null) continue;
        prop.SetValue(self, attr.Value);
    }
}

I haven't tested this, and there may be issues with certain types but I'll leave it to your consideration and discretion. Should you decide to implement this then improvements could certainly be made.

2 Comments

This seems awfully hacky and convoluted.
Well, I can't properly advocate it; but it is a possibility.
1

If you were to run this code, you would get a NullReferenceException because the field is never initialized.

class Program
{
    static void Main(string[] args)
    {
        Person sergio = new Person();
        sergio.Items.Add("test", "test");

        Console.ReadKey();
    }

    public class Person
    {
        public Dictionary<string, string> Items { get; set; }
    }
}

So one way to solve this would be to initialize it, in the class´s constructor.

class Program
{
    static void Main(string[] args)
    {
        Person sergio = new Person();
        sergio.Items.Add("test", "test");

        Console.ReadKey();
    }

    public class Person
    {
        public Dictionary<string, string> Items { get; set; }

        public Person()
        {
            Items = new Dictionary<string, string>();
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.