在C#中处理对象中的列表或词典的最佳方法是什么?

时间:2014-02-05 14:25:39

标签: c# oop

我经常创建包含列表或词典的对象

处理此问题的理想方法是什么?

例如:

class Person
{
    public List<person> Friends { get; set; }
}

但这意味着我需要在向其添加项目之前验证Friends是否已初始化。所以我有时会选择:

class Person
{
    public List<Person> Friends = new List<Person>();
}

但这显然不理想,因为它是一个公共领域。

我可以在构造函数中初始化,或者我也可以使用lazy instantiation:

class Person
{
    private List<Person> friends;

    public List<Person> Friends
    {
        get 
        {
            if (friends == null)
                friends = new List<Person>();
            return friends; 
        }
        set { friends = value; }
    }

}

但这真的很冗长。在任何情况下,没有任何选择似乎真的很好。

5 个答案:

答案 0 :(得分:3)

作为一种良好做法,您可以使用private set的属性并在constructor上初始化(由于您创建了Person对象,因此可以在哪里执行此操作),样品:

public class Person
{
    public List<Person> Friends { get; private set; }

    public Person() 
    {
       this.Friends = new List<Person>();
    }
}

答案 1 :(得分:2)

我(我猜大多数人)也会在构造函数中初始化它。 如果资源的创建成本很高,那么延迟初始化是值得的,你无法确定是否需要它。

对于列表和词典:只需在构造函数中初始化它们。

答案 2 :(得分:1)

如果增加的内存开销对你来说不是问题(并且很可能不是,除非你正在处理数百万个对象),最佳做法可能是跳过延迟初始化,标记字段{ {1}},并将其初始化为内联:

readonly

或者,可以将初始化程序移动到构造函数中。在这种情况下,它没有任何实际区别;这是一个风格决定。

似乎还没有令人迫切需要允许列表本身被外部代码替换,因此只需通过省略class Person { private readonly List<Person> friends = new List<Person>(); public List<Person> Friends { get { return friends; } } } 访问器使该属性为只读。

@ FelipeOriani的建议非常接近我的,是一个完全可以接受的选择。我个人更喜欢在适当时(特别是对于集合)强制执行set语义,确保它们只能在对象创建期间初始化,但这主要取决于个人偏好。

答案 3 :(得分:1)

您也可以尝试使用4.0

中提供的Lazy构造

所以你的代码可能如下:

class Person
{
    private Lazy<List<Person>> friends = new Lazy<List<Person>>();
    public Lazy<List<Person>> Friends {
         get { return friends; }
    }
}

答案 4 :(得分:0)

怎么样?
class Person
{
    private List<Person> friends;

    public List<Person> Friends
    {
        get { return friends ?? (friends = new List<Person>()); }
        set { friends = value; }
    }

}

相关问题