2009-12-01 25 views
10

Explicaré mi pregunta en un ejemplo. Tengamos siguiente código en C#:PowerShell: pasar bloques como parámetros a las funciones

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

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

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

La salida de este código es:

1 
2 
3 

Ahora, quiero escribir este código en PowerShell:

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

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

A { 
    3 
} 

Sin embargo, este código provoca un desbordamiento de profundidad de llamada:

El guion falló du e para llamar a profundidad desbordamiento. La profundidad llamada alcanzó 1001 y el máximo es 1000.

He encontrado que si cambio el nombre del parámetro de la función B, que va a funcionar.

¿Es una característica o un error (o ambas cosas)? ¿Cómo puedo hacer que funcione en PowerShell sin tener parámetros únicos en todas las funciones?

Respuesta

15

Sí, va recursivo porque la referencia $block en el scriptbloque pasado a la función B se evalúa en el contexto de la función B y, como resultado, evalúa el valor del parámetro $block de B.

Si no desea cambiar el nombre del parámetro (no se puede culpar a) puede forzar PowerShell para crear un nuevo cierre en A para capturar el valor de $ bloque dentro de la función Un ejemplo:

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

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

A {Write-Host 3} 
+0

Thx. ¿Hay algún atajo estándar para crear cierres desde bloques (por ejemplo, $ {})? –

+0

No. El único método que conozco es el método GetNewClosure(). –

+0

Keith Hill eres mi héroe! – bwerks

Cuestiones relacionadas