2010-10-28 9 views
10

tengo un método con la siguiente firma:C# - cómo pasar 'hacia fuera' de parámetros en la expresión lambda

private PropertyInfo getPropertyForDBField(string dbField, out string prettyName) 

En ella, creo que el valor asociado prettyName en base a la dada dbField. entonces yo quiero encontrar todas las propiedades, si las hay, que tienen el nombre prettyName, así que estoy tratando de hacer lo siguiente:

IEnumerable<PropertyInfo> matchingProperties = 
    getLocalProperties().Where(prop => 
     prop.Name.Equals(prettyName) 
    ); 

Sin embargo, esto da el siguiente error:

Cannot use ref or out parameter 'prettyName' inside an anonymous method, lambda expression, or query expression

Por el punto en el método donde estoy tratando de usar prettyName en el parámetro lambda Where, prettyName es definitivamente inicializado. I return si prettyName no se puede inicializar con un valor válido. ¿Hay algún truco que pueda hacer aquí para dejarme usar prettyName en la expresión lambda?

Edit: Estoy usando .NET 3.5 si es importante.

+1

¿Qué tal si almacenamos el valor que pondría a prettyName en una variable diferente para que pueda hacer 'prettyName = someval;' y luego usar 'someval' en su función anon? –

Respuesta

16

Como indica el error del compilador, no está permitido usar los parámetros out o ref dentro de las expresiones lambda.

¿Por qué no usar una copia? No es que la lambda quiera mutar la variable de todos modos, así que no veo un inconveniente.

string prettyNameCopy = prettyName; 
var matchingProperties = getLocalProperties() 
         .Where(prop => prop.Name == prettyNameCopy); 

Alternativamente, se puede utilizar un local a lo largo (para evaluar el nombre apropiado, etc.), y asignar el parámetro outprettyName justo antes de regresar del método. Esto probablemente será más legible si no hay una ramificación significativa dentro del método.

+0

... Bien, ahora solo me siento tonto. Estaba buscando cómo usar un "delegado" o algo loco para hacer esto. ¡Gracias! –

+0

Saludos. 'delegar' no habría ayudado mucho, ya que la misma restricción también se aplica a los delegados anónimos. – Ani

14

Solo para aclarar. Es posible usar argumentos de ref/out desde un método llamado en un lambda.

También puede usar un ref o out si especifica el tipo del parámetro. Lo que significa enviar prettyName como parámetro a la lambda.

(prop, ref string prettyName) => prop.Name.Equals(prettyName); 

Donde cláusula toma en un solo argumento, que es el elemento de propiedad en la lista. Esto es lo que le impide agregar un argumento a la lambda.

No quería dejar a las personas la falsa impresión de que no puede usar estos argumentos en una lambda. Simplemente no puedes usarlos por captura.

+0

UP VOTADO. Esto es exactamente lo que necesitaba. –

+0

Lee, por alguna razón no puedo hacer que esto funcione. El código que estoy usando es IEnumerable matchingProperties = getLocalProperties(). Where ((prop, ref string prettyName) => prop.Name.Equals (prettyName) ); ... pero da un error en el "ref" ("Una variable local llamada 'prettyName' no puede declararse en este ámbito porque daría un significado diferente a 'prettyName' que ya se usa en un ámbito principal o actual. –

+0

¿O estaba diciendo que todavía tiene que reasignar prettyName a una variable de cadena diferente, pero que luego podría pasarla por ref o out? –

Cuestiones relacionadas