2011-02-06 19 views
5

È possibile utilizzare un delegato anonimo per restituire un oggetto?Utilizzo di un delegato anonimo per restituire un oggetto

Qualcosa in questo modo:

object b = delegate { return a; }; 
+1

Dove non 'a' vengono? Anche il tuo codice esistente assegna semplicemente 'b' al delegato stesso. – BoltClock

+0

@BoltClock - grazie per aver segnalato il problema dell'assegnazione. – wulfgarpro

+0

vedi l'aggiornamento re il tuo dolore cross-threading –

risposta

9

Sì, ma solo invocando esso:

Func<object> func = delegate { return a; }; 
// or Func<object> func =() => a; 
object b = func(); 

E, naturalmente, il seguente è molto più semplice ...

object b = a; 

Nei commenti, le eccezioni cross-thread sono menzionati; questo può essere fissato come segue:

Se il delegato è la cosa che vogliamo correre di nuovo sul thread UI da un filo BG:

object o = null; 
MethodInvoker mi = delegate { 
    o = someControl.Value; // runs on UI 
}; 
someControl.Invoke(mi); 
// now read o 

O viceversa (per eseguire il delegato su un BG):

object value = someControl.Value; 
ThreadPool.QueueUserWorkItem(delegate { 
    // can talk safely to "value", but not to someControl 
}); 
+0

e se sto provando a confrontare 'a' con qualche altro oggetto all'interno di un metodo su un thread diverso dal thread in cui' a' appartiene? Ad esempio, 'void Test() {if (a == b) {}}' dove l'accesso a b da questo metodo causa un'eccezione cross-thread. – wulfgarpro

+0

@Wulfgar 'a' non" appartiene "a un thread; appartiene a un'istanza di classe (se si tratta di un campo) o è una variabile di metodo. In entrambi i casi, il compilatore "catturerà" la variabile 'a' dall'ambito che dichiara il delegato; creando un tipo che incapsula l'istanza dell'oggetto "this" (per un campo) o la "variabile" stessa; citato perché allora * diventa * un campo. –

+0

@Wulfgar: per ottenere un cross-thread, è necessario eseguire l'interfaccia utente; sì, è possibile risolvere questo problema, ma "come" dipende da quale blocco di codice è il codice dell'interfaccia utente; puoi chiarirlo per favore? –

1

Basta dichiarare qualche parte queste funzioni statiche:

public delegate object AnonymousDelegate(); 

public static object GetDelegateResult(AnonymousDelegate function) 
{ 
    return function.Invoke(); 
} 

E ovunque lo usano come si vuole in questo modo:

object item = GetDelegateResult(delegate { return "TEST"; }); 

e neppure come questo

object item = ((AnonymousDelegate)delegate { return "TEST"; }).Invoke(); 
0
using System; 

public delegate int ReturnedDelegate(string s); 

class AnonymousDelegate 
{ 
    static void Main() 
    { 
     ReturnedDelegate len = delegate(string s) 
     { 
      return s.Length; 
     }; 
     Console.WriteLine(len("hello world")); 
    } 
} 
Problemi correlati