2010-10-28 12 views
10

Ho un metodo con la seguente firma:C# - come passare 'fuori' dei parametri in espressione lambda

private PropertyInfo getPropertyForDBField(string dbField, out string prettyName) 

In essa, trovo il valore associato prettyName in base alla data dbField. poi voglio trovare tutte le proprietà, se del caso, che hanno il nome prettyName, quindi sto cercando di fare quanto segue:

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

Tuttavia, questo dà il seguente errore:

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

By il punto nel metodo in cui sto cercando di utilizzare prettyName nel parametro lambda Where, prettyName è stato inizializzato definitivamente. I return se prettyName non può essere inizializzato su un valore valido. C'è qualche trucco che potrei fare qui per permettermi di usare prettyName nell'espressione lambda?

Modifica: Sto usando .NET 3.5 se è importante.

+1

Che ne dici di memorizzare il valore che avresti assegnato a prettyName in una variabile diversa in modo da poter eseguire 'prettyName = someval; 'quindi utilizzare' someval' nella funzione anon? –

risposta

16

Come indica l'errore del compilatore, non è consentito utilizzare o rifare i parametri all'interno delle espressioni lambda.

Perché non usare solo una copia? Non è come se il lambda volesse modificare la variabile in ogni caso, quindi non vedo un rovescio della medaglia.

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

In alternativa, è possibile utilizzare un locale in tutta (per valutare il nome ecc appropriato), e assegnare il parametro prettyNameout poco prima di tornare dal metodo. Questo sarà probabilmente più leggibile se non vi è una ramificazione significativa all'interno del metodo.

+0

... Ok, ora mi sento solo sciocco. Stavo cercando come usare un 'delegato' o qualcosa di pazzo per farlo. Grazie! –

+0

Cheers. 'delegato' non sarebbe stato di grande aiuto in quanto la stessa restrizione si applica anche ai delegati anonimi. – Ani

14

Giusto per chiarire. È possibile utilizzare gli argomenti ref/out da un metodo chiamato in un lambda.

È inoltre possibile utilizzare un riferimento o un valore esterno se si specifica il tipo di parametro. Il che significa inviare prettyName come parametro al lambda.

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

Dove clausola accetta solo un argomento, che è l'elemento di proprietà nell'elenco. Questo è ciò che ti impedisce di aggiungere un argomento al lambda.

Non volevo lasciare alle persone la falsa impressione che non è possibile utilizzare questi argomenti in un lambda. Non puoi semplicemente usarli per cattura.

+0

SU VOTATI. Questo è esattamente ciò di cui avevo bisogno. –

+0

Lee, per qualche motivo non riesco a farlo funzionare. Il codice che sto usando è IEnumerable matchingProperties = getLocalProperties(). Dove ((prop, ref string prettyName) => prop.Name.Equals (prettyName) ); ... ma dà un errore sul "ref" ("Una variabile locale chiamata 'prettyName' non può essere dichiarata in questo ambito perché darebbe un significato diverso a 'prettyName' che è già utilizzato in un ambito genitore o corrente. –

+0

O stavi dicendo che devi ancora riassegnare prettyName a una variabile di stringa diversa, ma che potresti poi passarla in ref o out? –