2011-04-04 8 views
8
if ((new Func</*out*/ string, bool>((/*out*/ string uname) => .... 

más detalles: eso es parte de la función de inicio de sesión y solo quiero que mi función lambda cambie el usuario de inicio de sesión con un parámetro de salida y me dijo que el usuario inició sesión con su bool return.¿Hay algún truco para usar los parámetros 'out' dentro de la función lambda?

Realmente entiendo que puedo devolver el Tuple y luego obtener el valor de mi cadena pero quiero exactamente el parámetro para una mayor claridad personal. Será mejor que devuelva solo cadena con nulo si el usuario no inicia sesión, solo quiero saber si puedo usar los parámetros dentro de las funciones lambda.

Y realmente entiendo que el código con expresiones en los lugares de declaración no es tan limpio Pero ninguno me dijo si eso es realmente malo para el compilador.

+0

Nota, como tales expresiones lambda pueden tener parámetros 'ref/out'. Por ej. esto funciona: 'delegar bool Logger (fuera del nombre de la cadena); Logger f = (barra de cadenas de salida) => { bar = ""; // asigna return ... }; ' .. Solo que con' Action/Func' no puedes hacerlo. Necesitas tu propio delegado. – nawfal

Respuesta

5

Lambda expresiones no va a funcionar, pero para los delegados que debe estar bien utilizando un cuerpo de la declaración:

bool outval = false; // definite assignment 
Func<bool> func =() => { 
    return SomeMethod(out foo); 
}; 
bool returned = func(); 
// check both outval and returned 

Para los delegados ... Usted tendrá que definir su propio:

public delegate bool MyType(out string value); 
+0

Entonces ... Realmente no quería usar delegados aquí, pero ni siquiera sabía si podían funcionar bien aquí. – Cynede

+1

No, * desea * delegados aquí, probablemente no expresiones lambda. –

+0

Ok, sí, lo hago :) if ((new ChUname ((out string uname) => ... funciona bien. – Cynede

2

No se pueden usar los parámetros con una expresión lambda. Ver esto stackoverflow question

+1

Un poco confuso. Puede tener una lambda como '(int i, out int j) => ...', con la palabra clave 'out' en ella, y que lamda se puede asignar a una variable de tipo delegado. Sin embargo, no se puede asignar a un árbol de expresiones. La pregunta a la que se refiere, habla de capturar un parámetro 'out' de un método regular dentro de un lambda. Es como 'bool estático público. Método_normal (out int i) {/ * cuerpo del método normal */Acción f =() => {Console.WriteLine (i); }; ... ...} '. *** Este *** es ilegal. La lambda intenta capturar un parámetro 'out' del método que lo contiene. –

2

Si bien no puede utilizar la palabra clave out Encontré una solución que le permite básicamente lograr punteros de memoria de estilo C++ en .NET. I found this class debido a la razón por la que abriste esta pregunta de SO por no poder usar un parámetro de salida donde yo quería.

public class Ptr<T> 
{ 
    Func<T> getter; 
    Action<T> setter; 

    public Ptr(Func<T> g, Action<T> s) 
    { 
     getter = g; 
     setter = s; 
    } 

    public T Deref 
    { 
     get { return getter(); } 
     set { setter(value); } 
    } 
} 

Ejemplo de uso

private IDocumentSession _session = DocumentStore.OpenSession() 

var ptr = new Ptr<IDocumentSession>(
       () => _session, 
       newValue => _session = newValue)) 

session.Deref.SaveChanges(); 
session.Deref = DocumentStore.OpenSession(); 

yo uso esto en un programa por lotes que permite operaciones por lotes para controlar la sesión de lavado con RavenDB cuando necesito de control de sesión de grano fino y al mismo tiempo dejando un contexto de sesión ambiente. Palabra de advertencia No tengo idea de las implicaciones que tendría este tipo de código en una aplicación de producción de larga duración, ya que no estoy seguro de si esto podría confundir el GC y provocar que la memoria nunca sea recuperada.

Cuestiones relacionadas