很多时候我看过他们写代码的代码:
public class Detail
{
public Detail()
{
this.ColumnCtrl = new List<UserControl>();
}
public List<UserControl> ColumnCtrl { get; set; }
}
但如果我只写下面的内容 - 它的效果也非常好:
public class Detail
{
public List<UserControl> ColumnCtrl { get; set; }
}
有没有理由像第一个例子那样编写我的get-set类?
答案 0 :(得分:1)
是的,因为在实例化类时,永远不会初始化第二个示例。
在第一个示例中,以下语句将起作用:
var detail = new Detail();
detail.ColumnCtrl.Add(new UserControl());
然而在第二种情况下,除非您在使用之前自行初始化它,否则它将失败NullReferenceException
。
答案 1 :(得分:1)
第二个示例没有为属性创建新实例,如果在创建Detail
实例后直接访问它,则会抛出空引用异常。
在第一个例子中,他们确保不会发生这种情况。
答案 2 :(得分:1)
第一个始终确保返回List的实例,因为构造函数创建了一个新实例。如果你在构造函数中没有它,它将在属性中返回null。
如果你那么:
Detail myInstance = new Detail();
myInstance.ColumnCtrl.Add........ //NullReferenceException is thrown here!
答案 3 :(得分:1)
有理由按照第一个例子中的方式编写它。它是属性的初始化。在第二种情况下,如果键入:
var detail = new Detail();
var count = detail.ColumnCtrl.Count
你会得到异常,因为ColumnCtrl没有被初始化。
您并不总是需要初始化,例如使用依赖项注入时,或者如果在ColumnCtrl getter中检查null并在第一次请求时初始化它,则无需初始化。
答案 4 :(得分:0)
在第二种情况下,ColumnCtrl未分配值。在第一种情况下,您确保默认情况下为ColumnCtrl分配一个空列表。
答案 5 :(得分:0)
您的第一个示例在构建ColumnCtrl
类时将Detail
属性初始化为值,其中第二个属性将保留为null
。如果它没有在其他地方初始化,那么您应该期待NullReferenceException
s。
只要在使用第二个示例之前显式初始化ColumnCtrl
属性,它们就完全相同。
Detail newDetail = new Detail();
newDetail.ColumnCtrl = new List<UserControl>();
newDetail.ColumnCtrl.Add(new UserControl());
另一种方法(虽然稍微冗长一点)是懒惰地实例化ColumnCtrl
属性,以消除构造Detail
时实例化它的开销:
public class Detail
{
public Detail()
{
this.ColumnCtrl = new List<UserControl>();
}
private List<UserControl> columnCtrl = null;
public List<UserControl> ColumnCtrl
{
get
{
// Missing appropriate locking mechanisms for brevity
if (columnCtrl == null)
columnCtrl = new List<UserControl>();
return columnCtrl;
}
// The set is not absolutely necessary if you never need to set it
// from outside of Details but if you do...
set
{
columnCtrl = value;
}
}
}