0

好的,我们有一个包含属性的类 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

4 回答 4

5

Collection以只读方式公开:

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

使用以前的实现_comments现在向调用者公开。允许客户端添加/删除您要实现的项目Add以及Remove从内部列表中添加/删除的成员。

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

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

或者,您可以实现自己 的,为您的和方法IList提供正确的实现。AddRemove

于 2012-07-16T18:28:33.003 回答
0

没有办法限制公开的 esposedList<T>课程。如果你List<T>在你的应用程序中没有过多地使用 ponetial,我建议你只包装那个列表。

说:

pulbic void AddComment(TaskComment task)
{
    /*Some validation on task parameter*/

    taskComments.Add(task);
}

并从财产或整个财产本身中删除公共get访问者(*如果可能的话)Comments

于 2012-07-16T18:30:23.790 回答
0

您的 setter 中的值对象将是 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 集合

于 2012-07-16T18:36:09.353 回答
0

将私有字段保留为列表,但更改您的属性,使其为只读且为 IEnumerable。然后像其他人建议的那样实现一个特定的 Add 方法来访问私有字段。这样,您的调用者可以自由地遍历集合,但必须使用 add 方法来添加它,给您一个验证的地方,等等,并抛出异常或返回成功代码。

返回具体的集合类型会限制您对未来更改的选择。然而,返回一个接口允许您更改底层集合,而不影响调用者。

当 List 具有隐式 IEnumerable 支持时,新建 ReadOnlyCollection 似乎很浪费。

于 2012-07-16T19:59:50.390 回答