简体   繁体   中英

How to initialize auto-property to not null in C#?

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.

Thanks!

没有显式的私有变量,唯一的另一种方法是将一些代码添加到类的构造函数中:

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

You can initialize it in your constructor:

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

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.

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>();

您必须使用显式支持字段,不能更改自动属性的getter或setter。

Initialize it in the constructor

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

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.

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>();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM