好的,我们有包含属性的类Ticket:
List<TaskComment> Comments;
我设置了back属性,以便我可以进行一些验证:
private List<TaskComment> _comments;
public List<TaskComment> Comment
{
get
{ //stuff }
internal set
{ //stuff }
}
尽管将set设置为internal,但Add()方法仍然在程序集外部公开。但无论如何,我想要做的是设置评论对象的ticketId属性,因为它被添加到集合中。例如:
var ticket = new TaskTicket();
var comment = new TaskComment { //initializers }
ticket.Comments.Add(comment);
--inside the ticket:
public List<TaskComment> Comments
{
get{ //stuff }
set
{
((TaskComment)value).TicketId = this._ticketId;
}
}
但这不起作用。它告诉我它无法从TaskComment转换为MyLibrary.TaskComment。这对我来说真的没有任何意义。但除此之外,无论如何,这感觉不对。那么在将传入的值/对象添加到类的集合之前,我究竟该如何修改它?
答案 0 :(得分:5)
将Collection
公开为只读:
public IReadOnlyCollection<TaskComment> Comments
{
get { return new ReadOnlyCollection(_comments); }
}
使用先前的实现_comments
现在向调用者公开。允许客户端添加/删除您实施Add
和Remove
成员的项目,这些成员会从内部列表中添加\ remove。
public void Add(Comment comment)
{
/* code */
_comments.Add(comment);
}
public void Remove(Comment comment)
{
/* code */
_comments.Remove(comment);
}
或者,您可以implement your own IList
为Add
和Remove
方法提供正确的实施方案。
答案 1 :(得分:0)
你无法限制 pubblicly esposed List<T>
类。
如果你没有在你的应用程序中使用List<T>
的ponetial太多,我建议只包装该列表。
说:
pulbic void AddComment(TaskComment task)
{
/*Some validation on task parameter*/
taskComments.Add(task);
}
并从get
属性或整个属性本身删除公开Comments
访问者(* ,如果这是可能的话)
答案 2 :(得分:0)
setter中的value对象将是List类型,因此当你将它强制转换为类型TaskComment时,它会抛出错误。在你的代码中你可以做到
var comment = new TaskComment { //initializers }
comment.TicketId = ticket.TicketId; //where TicketId is a public property for _ticketId
ticket.Comments.Add(comment);
或者您可以重载Add()方法以将注释添加到Comment集合
答案 3 :(得分:0)
将私有字段保留为List,但更改属性以使其只读并且是IEnumerable。然后像其他人建议的那样实现一个访问私有字段的特定Add方法。通过这种方式,您的调用者可以自由地迭代集合,但必须使用add方法添加到集合中,为您提供验证等位置并抛出异常或返回成功代码。
返回具体集合类型会限制您对未来更改的选择。然而,返回接口允许您更改基础集合而不会对调用者产生任何影响。
当List具有隐含的IEnumerable支持时,新建ReadOnlyCollection似乎很浪费。