使用.Add
将类的实例添加到通用列表不起作用。
为了说明问题,这里有两个简单的示例类:
public class WorkOrder
{
private List<Note> _Notes;
public List<Note> Notes
{
get
{
return _Notes ?? new List<Note>();
}
set
{
_Notes = value;
}
}
}
public class Note
{
public string NoteText { get; set; }
public System.DateTime Time { get; set; }
public string User { get; set; }
}
您可能会注意到get
属性WorkOrder.Notes
中的编码。我把它放进去,所以财产不会用空值初始化(参考我在SO here上发布的另一个问题的答案)。
利用这些课程:
public void Test()
{
WorkOrder tempWorkOrder = new WorkOrder();
Note tempNote = new Note()
{
User = "Aaron",
Time = DateTime.Now,
NoteText = "Work Order pulled from CSV Excel report."
};
tempWorkOrder.Notes.Add(tempNote);
}
我希望Test()
中的最后一行将tempNote
添加到Note
中的tempWorkOrder
列表中。但是,此行完成后tempWorkOrder.Notes
为空。不会抛出任何错误或异常。
我正在使用VS2013 Express。
我做错了什么?
答案 0 :(得分:15)
private List<Note> _Notes;
public List<Note> Notes
{
get
{
return _Notes ?? new List<Note>();
}
set
{
_Notes = value;
}
}
get
错了。它应该是:
get
{
if (_Notes == null) {
_Notes = new List<Note>();
}
return _Notes;
}
因为否则您不会保存自己创建的new List<Note>()
,并且每次使用get
重新创建get
时new List<Note>()
都会返回_Notes
但不会修改get
,以便每次_Notes
检查null
,查看new List<Note>()
并返回get
)
请注意,如果您讨厌这个世界(以及您的其他程序员),您可以将return _Notes ?? (_Notes = new List<Note>());
压缩为:
{{1}}
(参见Ternary/null coalescing operator and assignment expression on the right-hand side?)我并不厌恶这个世界(以及我的其他程序员)这样做: - )
答案 1 :(得分:1)
您还没有在那里创建列表。您需要向WorkOrder
添加构造函数,因为您无法添加到不存在的集合。这样,每当您创建工作订单时,您将在`_Notes'字段中有一个空列表。
它看起来像这样:
WorkOrder(){
_Notes = new List<Note>();
}
答案 2 :(得分:1)
如果您使用的是C#8,则应该可以使用null-coalescing分配,例如:
get => _Notes ??= new List<Note>();
带有括号:
get
{
return _Notes ??= new List<Note>();
}
答案 3 :(得分:0)
您永远不会指定_Notes
改为
private List<Note> _Notes;
public List<Note> Notes
{
get
{
if(_Notes == null)
_Notes = new List<Note>();
return _Notes;
}
set
{
_Notes = value;
}
}
答案 4 :(得分:0)
在Notes
的getter中,您无法保存对新创建的列表的引用。因此,每次访问该getter时,您都会获得一个新的空列表。所以这个:
tempWorkOrder.Notes.Add(tempNote);
...正在将tempNote
添加到立即丢弃的List<Note>
。
答案 5 :(得分:0)
问题是你的get方法:
get
{
return _Notes ?? new List<Note>();
}
由于您没有将要创建的对象的引用分配给_Notes
,因此它保持为null,并且您已分配给未在其他任何位置引用的列表。
这是你可以做的事情:
get
{
if (_Notes == null)
_Notes = new List<Note>();
return _Notes;
}
答案 6 :(得分:0)
您尚未初始化_Notes
。
因此,当List<Note>
为空时,当您获得_Notes
时,它不会将对象分配给_Notes
。每次访问公共属性时,它都会返回不同的List<Note>
,这就是Add()
调用似乎不起作用的原因。
你应该使用:
get
{
if (_Notes == null)
_Notes = new List<Note>();
return _Notes;
}
答案 7 :(得分:0)
public class WorkOrder
{
public List<Note> Notes {get;set;}
public WorkOrder()
{
Notes = new List<Note>();
}
}
但是在C#6.0中你应该能够做到以下几点:
public class WorkOrder
{
public List<Note> Notes {get;set;} = new List<Note>();
}
答案 8 :(得分:0)
晚了聚会,您可以创建一个小的扩展方法来防止空列表或空列表:
public static bool NotNullAndEmpty<T>(this IEnumerable<T> source)
{
if (source != null && source.Any())
return true;
else
return false;
}
此外,如果您正在使用数据库,则建议使用IEnumerable
并使用IEnumerable
进行所有修改。完成后,调用.ToList(
),这将导致对数据库的一次调用。