【发布时间】:2018-01-20 11:08:48
【问题描述】:
在 Javascript 中,内部函数可以访问外部函数的变量。所以在下面的例子中,objFlag 可以在 this.depthTraverse 函数中访问。
Tree.prototype.findNodeWithValue = function(valueToFind){
var objFlag = {found: false, node: null}
this.depthTraverse(function(foundNode){
if(foundNode.data === valueToFind){
objFlag.found = true;
objFlag.node = foundNode;
}
})
return objFlag
}
我正在尝试以相同的方式在 C# 中编写等效的代码,但我意识到我遇到了一些范围界定问题。 FWIW,我不熟悉使用委托、函数或动作,所以我肯定会遗漏一些东西,但对我来说,似乎即使我可以在 C# 中传递一个方法,它也无法访问任何外部变量它被调用的函数?有没有办法编写与上述代码本质上等效的内容,但是在 C# 中?而且我要求的不是相同的输出或结果,而是要求以相同的方式传入函数并改变外部变量状态。
depthTraverse 下面的实现供参考:
Tree.prototype.depthTraverse = function(fn){
var queue = [];
queue.push(this.root);
while(queue.length > 0){
var nodeToInspect = queue.pop();
if(nodeToInspect.leaves.length !== 0){
queue.unshift(...nodeToInspect.leaves) // breadth first
}
if(fn){
fn(nodeToInspect);
}
}
}
----- 更新 ------
我相信我根据@JonWeeder 的回答得出了一个解决方案。下面:
private static Node<T> holder {get;set;}
public Node<T> FindValue(T value){
Node<T> node;
TraverseDFS(value, (el) => {
if(Comparer<T>.Equals(el.Value, value)){
holder = el;
}
});
node = holder;
holder = null;
return node == null ? null : node;
}
private void TraverseDFS(T value, Action<Node<T>> action)
{
var queue = new List<Node<T>>();
queue.Add(this.Root);
while(queue.Count > 0){
var currentNode = queue[0];
queue.RemoveAt(0);
if(currentNode.Leaves.Count > 0){
queue.AddRange(currentNode.Leaves);
}
action(currentNode);
}
}
这是尽可能接近 Javascript 的实现。尽管未经测试,IDE 并没有抱怨。
【问题讨论】:
-
@zzxyz 这个例子是匿名方法,不是本地方法。
-
@Servy 我认为这篇文章很好地解决了范围界定问题,并提供了适用于 C# 7 之前的解决方案。我也不确定您指的是哪个示例。如果您指的是链接,那么肯定有几个不是匿名的例子。不过,我可能误解了你的意思。
标签: javascript c# scope callback delegates