我在哪里失去了参考?
我正在尝试使用访问者模式,如下所示:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为此,首先“newItem”必须是“ref”。 其次,您需要在委托调用后对更新后的值执行某些操作(枚举器不提供任何更新内容的功能)。 但无论如何,大多数集合更新都会破坏枚举器!
否则,您的替换“newItem”将对客户端不可见。 但是,标签的属性会发生变化(假设它是引用类型并且可变)。
为此,itemsToActOn 必须是
IList
- 那么您可以使用:或者如果您可以使用
T Visit(T)
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:Or if you could use
T Visit(T)
是的,你是对的 - 但我在那个地方使用了 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.