在Javascript中,內部函數可以訪問外部函數的變量。因此在下面的示例中,可以在this.depthTraverse
函數中訪問objFlag
。作用域,C中的變量訪問#
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);
}
}
}
------ UPDATE ------
我相信,我來到了基於@ 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並不抱怨。
https://asizikov.github.io/2016/04/15/thoughts-on-local-functions/ – zzxyz
@zzxyz這個例子是一個匿名方法,而不是本地方法。 – Servy
@Servy我認爲本文在解決範圍問題方面做得很好,並提供了在C#7之前工作的解決方案。我也不確定您指的是什麼樣的示例。如果你指的是鏈接,肯定有幾個例子不是匿名的。不過,我可能會誤解你的觀點。 – zzxyz