我在哪里失去了参考?

发布于 2024-07-08 22:48:10 字数 1475 浏览 9 评论 0原文

我正在尝试使用访问者模式,如下所示:

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 = findTag 之后 - 我希望在访问者的 foreach 中我会得到新值 - 显然这不会发生。

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

http://discuss.joelonsoftware.com/default.asp?dotnet.12.521767。 19

I'm trying to use the Visitor Pattern and I have as follows:

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.
  }
}

The visitor :

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
}

And where I'm calling the visitor :

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

So .. where am I losing the reference ?
after newItem = foundTag - I expect that in the foreach in the visitor I would have the new value - obviously that's not happening.

Edit I think I found the answer - in a foreach the variable is readonly.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

公布 2024-07-15 22:48:11

为此,首先“newItem”必须是“ref”。 其次,您需要在委托调用后对更新后的值执行某些操作(枚举器不提供任何更新内容的功能)。 但无论如何,大多数集合更新都会破坏枚举器!

否则,您的替换“newItem”将对客户端不可见。 但是,标签的属性会发生变化(假设它是引用类型并且可变)。

为此,itemsToActOn 必须是 IList - 那么您可以使用:

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]);
}

For that to work, firstly "newItem" would have to be "ref". Secondly, you'd need to do something with the updated value after the delegate invoke (an enumerator doesn't offer any ability to update contents). But most updates to collections will break enumerators anyway!

Your replacing "newItem" will not be visible to the client otherwise. However, changes to properties of the tag (assuming it is a reference type and mutable) will be.

For this to work, itemsToActOn would have to be IList<T> - then you could use:

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

Or if you could use T Visit(T)

for(int i = 0 ; i < itemsToActOn.Count ; i++)
{
    itemsToActOn[i] = visitor.Visit(itemsToActOn[i]);
}
铁憨憨 2024-07-15 22:48:11

是的,你是对的 - 但我在那个地方使用了 IEnumerable,所以不能真正对其进行 for 操作。

不过我想返回一个新列表而不是影响当前列表更正确。 所以我使用的是 ValueReturningVisitor - 灵感来自 Jean-Paul S. Boodhoo。

Yes, you're right - but I'm using an IEnumerable in that place so can't really do a for on it.

However I guess it's more correct to return a new list instead of affecting the current one. So I'm using a ValueReturningVisitor - inspired(taken?:) ) from Jean-Paul S. Boodhoo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文