2015-07-17 5 views
6

Sto lavorando a un'applicazione Windows Form e contiene controlli personalizzati con metodi che possono potenzialmente essere chiamati da thread diversi dal thread dell'interfaccia utente. Quindi, questi metodi pertanto sembrano un po 'come questo per evitare eccezioni:Converti in modo implicito il gruppo di metodi in Delegato (per argomento di Control.Invoke)

public void DoSomeStuff() 
{ 
    if (InvokeRequired) 
    { 
     Invoke((Action)DoSomeStuff); 
    } 
    else 
    { 
     // Actually do some stuff. 
    } 
} 

Il cast esplicito del gruppo metodo di DoSomeStuff a un Action attirato la mia attenzione, e così ho cercato in delegati e altri argomenti correlati più profondamente di quello che ho prima.

Anche se ho visto alcune domande relative qui, non sono stato in grado di trovare esattamente la risposta al mio, che è:

Perché il gruppo metodo DoSomeStuff richiedono cast esplicito a un Action in questo Astuccio?

Se rimuovo il cast, tanto sono due errori:

errore 102 Argomento 1: non può convertire da 'gruppo metodo' a 'System.Delegate'

Errore 101 Il meglio partita metodo di overload per 'System.Windows.Forms.Control.Invoke (System.Delegate, pARAMS oggetto [])' ha alcuni argomenti non validi

Il Il fatto che il compilatore sia apparentemente confuso su quale sovraccarico di Invoke usi sembra un suggerimento abbastanza grande, ma non sono ancora sicuro sul perché esattamente non riesca a capirlo. Mi aspetto che il compilatore deduca che il primo sovraccarico di Invoke, che accetta un singolo argomento Delegate, è quello che dovrebbe essere utilizzato.

mi aspetterei che, poiché non v'è alcun problema se il codice è scritto in questo modo:

Action a = DoSomeStuff; 
Invoke(a); 

Il metodo del gruppo DoSomeStuff può essere implicitamente convertito nel tipo Action delegato e Action deriva (tecnicamente?) Da System.Delegate, quindi Invoke può gestire l'argomento a senza alcun problema. Ma allora perché la conversione implicita non può essere eseguita dal compilatore quando provo a passare direttamente l'argomento DoSomeStuff? Ad essere onesti, non sono convinto dalla mia logica qui, ma non sono ancora sicuro di cosa mi manchi.

risposta

2

Il problema non è che il compilatore abbia problemi nel selezionare un sovraccarico. Il sovraccarico di "corrispondenza migliore" è quello desiderato ma ha argomenti non validi. Il linguaggio C# non definisce alcuna conversione implicita dal gruppo di metodi (DoSomeStuff) a System.Delegate.

Si potrebbe dire che il compilatore deve semplicemente scegliere uno dei tipi Action/Func e questo è stato richiesto come funzione lingua. In questo momento questo non fa parte di C#. (Non so perché, spero che la richiesta della lingua vada a buon fine.)

System.Windows.Forms.Control.Invoke è stato creato in .NET 1.0. Oggi, si sarebbe utilizzare le seguenti firme:

void Invoke(Action action); 
Task InvokeAsync(Action action); 

E sarebbe semplicemente lavorare.

Provare a effettuare la migrazione a await e ciò si interrompe.

+0

> Si potrebbe dire che il compilatore deve semplicemente scegliere uno dei tipi di azione/Func e questo è stato richiesto come funzione lingua Questo molto facilmente si rompe: 'void Foo (out stringa abc);' Non è rappresentabile usando 'Azione' o' Func'. Se implementano l'inferenza di azione/funzione come una funzione del linguaggio, questa funzione verrà interrotta. – GeirGrusom

+0

@GeirGrusom con questa particolare firma la conversione potrebbe fallire (staticamente). È un caso raro, penso che sia giusto mostrare un errore qui. Non tutti i metodi possono essere rappresentati come azioni/funzioni, ma il 99% di esse può essere in pratica. Tutti i tipi di delegati dovrebbero essere trattati strutturalmente con conversioni implicite dove ha senso. – usr

+0

Non penso che sia okay. L'errore è mostrato perché la funzionalità è fondamentalmente danneggiata. – GeirGrusom