代码之家  ›  专栏  ›  技术社区  ›  sirrocco

我在哪里失去推荐信?

  •  1
  • sirrocco  · 技术社区  · 16 年前

    我尝试使用访客模式,我有以下几点:

    public class EnumerableActions<T> : IEnumerableActions<T>
    {
    private IEnumerable<T> itemsToActOn;
    
    
    public EnumerableActions ( IEnumerable<T> itemsToActOn )
    {
      this.itemsToActOn = itemsToActOn;
    }
    
    public void VisitAllItemsUsing ( IVisitor<T> visitor )
    {
      foreach (T t in itemsToActOn)
      {
        visitor.Visit ( t );// after this, the item is unaffected.
      }
    }
    

    来访者:

    internal class TagMatchVisitor : IVisitor<Tag>
    {
    private readonly IList<Tag> _existingTags;
    
    public TagMatchVisitor ( IList<Tag> existingTags )
    {
      _existingTags = existingTags;
    }
    
    #region Implementation of IVisitor<Tag>
    
    public void Visit ( Tag newItem )
    {
      Tag foundTag = _existingTags.FirstOrDefault(tg => tg.TagName.Equals(newItem.TagName, StringComparison.OrdinalIgnoreCase));
    
      if (foundTag != null)
        newItem = foundTag; // replace the existing item with this one. 
    }
    
    #endregion
    }
    

    我打电话给来访者的地方是:

    IList<Tag> tags = ..get the list;
    tags.VisitAllItemsUsing(new TagMatchVisitor(existingTags));
    

    所以…我在哪里失去推荐信? 在newitem=foundtag之后——我希望在访问者的foreach中有新的值——显然这不会发生。

    编辑 我想我找到了答案-在foreach中,变量是只读的。

    http://discuss.joelonsoftware.com/default.asp?dotnet.12.521767.19

    2 回复  |  直到 15 年前
        1
  •  1
  •   Marc Gravell    16 年前

    要实现这一点,首先“newitem”必须是“ref”。其次,在委托调用之后,您需要对更新的值进行一些处理(枚举器不提供任何更新内容的能力)。但对集合的大多数更新都会破坏枚举器!

    否则,客户端将看不到您替换的“newitem”。但是,更改为 性质 标签的(假设它是引用类型并且是可变的)将是。

    为了实现这一点,itemstoacton必须 IList<T> -然后你可以使用:

    for(int i = 0 ; i < itemsToActOn.Count ; i++)
    {
        T value = itemsToActOn[i];
        visitor.Visit(ref t)
        itemsToActOn[i] = value;
    }
    

    或者你可以用 T Visit(T)

    for(int i = 0 ; i < itemsToActOn.Count ; i++)
    {
        itemsToActOn[i] = visitor.Visit(itemsToActOn[i]);
    }
    
        2
  •  0
  •   sirrocco    16 年前

    是的,你是对的-但是我在那个地方使用了一个IEnumerable,所以不能真正在上面做a。

    不过,我想返回一个新列表而不是影响当前列表更为正确。所以我用的是一个受游客启发的价值回归(采取了吗?:)来自Jean-Paul S.Boodhoo。