如何验证正在添加到集合属性的项目?

时间:2012-07-16 18:25:45

标签: c# .net

好的,我们有包含属性的类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。这对我来说真的没有任何意义。但除此之外,无论如何,这感觉不对。那么在将传入的值/对象添加到类的集合之前,我究竟该如何修改它?

4 个答案:

答案 0 :(得分:5)

Collection公开为只读:

public IReadOnlyCollection<TaskComment> Comments
{
   get { return new ReadOnlyCollection(_comments); }
}

使用先前的实现_comments现在向调用者公开。允许客户端添加/删除您实施AddRemove成员的项目,这些成员会从内部列表中添加\ remove。

public void Add(Comment comment)
{
    /* code */
    _comments.Add(comment);
}

public void Remove(Comment comment)
{
    /* code */
    _comments.Remove(comment);
}

或者,您可以implement your own IListAddRemove方法提供正确的实施方案。

答案 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似乎很浪费。