2009-12-01 25 views
10

Ich werde meine Frage an einem Beispiel erläutern. Lassen Sie uns folgenden Code in C#:PowerShell: Blöcke als Parameter an Funktionen übergeben

void A(Action block) 
{ 
B(() => 
{ 
    Console.WriteLine(2); 
    block(); 
}); 
} 

void B(Action block) 
{ 
Console.WriteLine(1); 
block(); 
} 

void Main() 
{ 
A(() => 
{ 
    Console.WriteLine(3); 
}); 
} 

Der Ausgang dieses Codes ist:

1 
2 
3 

Nun, ich diesen Code in Powershell schreiben möchten:

function A($block) { 
    B { 
     2 
     . $block 
    } 
} 

function B($block) { 
    1 
    . $block 
} 

A { 
    3 
} 

jedoch dieser Code verursacht einen Anruf Tiefe Überlauf:

Das Skript fehlgeschlagen du e zum Anruf Tiefe Überlauf. Der Anruf erreichte Tiefe 1001 und das Maximum ist 1000.

ich gefunden, wenn ich den Namen des Parameters der Funktion B zu ändern, wird es funktionieren.

Ist es eine Funktion oder ein Fehler (oder beides)? Wie kann ich das in PowerShell durchführen, ohne Parameter zu haben, die über Funktionen hinweg einzigartig sind?

Antwort

15

Yeah, du gehst rekursiv, weil die $block Referenz im Skriptblock, die in Funktion B übergeben wurde, im Kontext von Funktion B ausgewertet wird und als Ergebnis den Wert von B's $block Parameter auswertet.

Wenn Sie nicht wollen, die Parameternamen ändern (tadeln Sie nicht), können Sie Powershell zwingen, einen neuen Verschluss in A zu schaffen, um den Wert von $ Block innerhalb Funktion A zB zu erfassen:

function A($block) 
{  
    B {Write-Host 2; &$block}.GetNewClosure() 
} 

function B($block) 
{ 
    Write-Host 1 
    &$block 
} 

A {Write-Host 3} 
+0

Thx. Gibt es eine Standardverknüpfung zum Erstellen von Schließungen aus Blöcken (z. B. $ {})? –

+0

Nein. Nur die GetNewClosure() -Methode ist mir bekannt. –

+0

Keith Hill du bist mein Held! – bwerks

Verwandte Themen