C#列表<;T>;。添加未正确添加
使用C#列表<;T>;。添加未正确添加,c#,C#,使用.Add将类的实例添加到泛型列表中不起作用 为了说明这个问题,这里有两个简单的示例类: public class WorkOrder { private List<Note> _Notes; public List<Note> Notes { get { return _Notes ?? new List<Note>(); } set
.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; }
}
我希望Test()
中的最后一行将tempNote
添加到tempWorkOrder
中的Note
列表中。但是,此行完成后,tempWorkOrder.Notes
为空。不会引发任何错误或异常
我正在使用VS2013 Express
我做错了什么?您还没有在那里创建列表。您需要将构造函数添加到
工作顺序中,因为您无法添加到不存在的集合中。这样,无论何时创建工单,“备注”字段中都会有一个空列表
它看起来像这样:
WorkOrder(){
_Notes = new List<Note>();
}
WorkOrder(){
_注释=新列表();
}
否则,您不会保存创建的new List()
,每次使用get
时都会重新创建它(get
返回new List()
,但不会修改\u Notes
,因此每次get
都会检查\u Notes
,请查看它的null
并返回新列表()
)
请注意,如果您讨厌这个世界(以及您的程序员同伴),您可以压缩get
:
return _Notes ?? (_Notes = new List<Note>());
return\u Notes??(_Notes=新列表());
(请参阅)我对这个世界(以及我的程序员同事)的憎恨还不够深,无法做到这一点:-)你从来没有分配过\u Notes
改为这样做
private List<Note> _Notes;
public List<Note> Notes
{
get
{
if(_Notes == null)
_Notes = new List<Note>();
return _Notes;
}
set
{
_Notes = value;
}
}
private List\u Notes;
公开名单注释
{
得到
{
如果(_Notes==null)
_注释=新列表();
还票;;
}
设置
{
_注释=价值;
}
}
在注释的getter中,您没有保存对新创建列表的引用。因此,每次访问该getter时,都会得到一个新的空列表。因此:
tempWorkOrder.Notes.Add(tempNote);
…正在将tempNote
添加到立即丢弃的列表中。问题在于获取方法:
get
{
return _Notes ?? new List<Note>();
}
您没有初始化注释
因此,当\u Notes
为空时,返回列表时,它不会将对象分配给\u Notes
。每次访问公共属性时,它都会返回不同的列表
,这就是为什么Add()
调用似乎不起作用的原因
你应该使用:
get
{
if (_Notes == null)
_Notes = new List<Note>();
return _Notes;
}
get
{
如果(_Notes==null)
_注释=新列表();
还票;;
}
公共类工作订单
{
公共列表注释{get;set;}
公共工单()
{
注释=新列表();
}
}
但在C#6.0中,您应该能够做到以下几点:
public class WorkOrder
{
public List<Note> Notes {get;set;} = new List<Note>();
}
公共类工作订单
{
公共列表注释{get;set;}=new List();
}
迟到时,您可以创建一个小的扩展方法来防止空列表或空列表:
public static bool NotNullAndEmpty<T>(this IEnumerable<T> source)
{
if (source != null && source.Any())
return true;
else
return false;
}
公共静态bool NotNullAndEmpty(此IEnumerable源代码)
{
if(source!=null&&source.Any())
返回true;
其他的
返回false;
}
另外,如果您使用的是数据库,建议使用IEnumerable
并使用IEnumerable
进行所有修改。完成后,调用.ToList(
),这将导致对数据库的单个调用。如果您使用的是C#8,则应该可以使用空合并赋值,如下所示:
get=>\u Notes???=newlist()代码>
括号内:
get
{
返回_Notes???=新列表();
}
在EF中(这是OP在另一个问题中所做的)这是初始化ICollections的正常方法。只想指出:这个问题是针对一个不与EF绑定的类的-虽然是的,它可以很容易地在代码优先的情况下应用。我不会懒洋洋地创建列表的实例-你可能会导致一些意外的行为。return\u Notes??新列表();执行以下操作,如果_Notes不为null,则返回它;如果为null,则创建并返回一个新列表,但从未分配给_Notes。就是这样。看起来到目前为止所有的答案都是正确的,但这一个答案最完整。谢谢大家!我没有收到返回注释的“仇恨”??(_Notes=新列表())代码>。我认为它非常清晰,事实上我更喜欢它,而不是一行if
。链接的线程显示出一些误用的可能性,但您几乎可以误用所有内容。@Corak单行if是因为我直接在的编辑器中编写,因此不会自动缩进:-)我总是使用if{}
。另一个表达式中=
的“仇恨”可能与编写代码的“一行一效”方式和/或C/C++@xanatos中=
赋值与=
相等运算符引起的大量错误有关-谢谢,我明白了。好吧,有了“一行,一个效果”,Linq方法链接就走不远了@Corak没有,因为Linq方法没有副作用(链的每个成员都会产生新的东西),所以它们是可以的。
get
{
if (_Notes == null)
_Notes = new List<Note>();
return _Notes;
}
get
{
if (_Notes == null)
_Notes = new List<Note>();
return _Notes;
}
public class WorkOrder
{
public List<Note> Notes {get;set;}
public WorkOrder()
{
Notes = new List<Note>();
}
}
public class WorkOrder
{
public List<Note> Notes {get;set;} = new List<Note>();
}
public static bool NotNullAndEmpty<T>(this IEnumerable<T> source)
{
if (source != null && source.Any())
return true;
else
return false;
}