我经常创建包含列表或词典的对象
处理此问题的理想方法是什么?
例如:
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; }
}
}
但这真的很冗长。在任何情况下,没有任何选择似乎真的很好。
答案 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
版
所以你的代码可能如下:
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; }
}
}