2014-04-23 12 views
14

ho una classe di base che ha una proprietà bool che assomiglia a questo:Impossibile convertire espressione lambda al tipo 'oggetto', perché non è un tipo delegato

public abstract class MyBaseClass 
{ 
    public bool InProgress { get; protected set; } 
} 

sto ereditare un'altra classe da esso e cercando di aggiungere InProgress come delegato al dizionario. Ma mi getta un errore. Questo è come la mia classe Derived assomiglia:

public abstract class MyClass 
{ 
    Dictionary<string, object> dict = new Dictionary<string, object>(); 
    dict.Add("InProgress", InProgress => base.InProgress = InProgress); 

} 

Questo è l'errore che sto ottenendo:

Impossibile convertire espressione lambda al tipo 'oggetto', perché non è un tipo delegato

Cosa sto facendo male qui?

+8

Esattamente come dice il messaggio di errore: hai un'espressione lambda e stai provando a convertirla in 'oggetto'. A quale tipo di delegato hai * voluto * convertirlo, e come ti aspettavi che il compilatore lo sapesse? –

+1

Perché stai cercando di aggiungere una lambda a un dizionario? –

+4

@DStanley Non è insolito, vero? – Rawling

risposta

14

migliore sarebbe quella di avere il dizionario fortemente tipizzato, ma se si assegna il lambda ad un lambda specifica (delegato) prima, dovrebbe funzionare (perché il compilatore quindi conosce il formato delegato):

 Action<bool> inp = InProgress => base.InProgress = InProgress; 
     dict.Add("InProgress", inp); 

O lanciando direttamente, stesso effetto

 dict.Add("InProgress", (Action<bool>)(InProgress => base.InProgress = InProgress)); 

Naturalmente avere un formato tale dizionario come oggetto è discutibile, dal momento che dovrete conoscere il formato delegato per essere in grado di usarlo.

+0

Grazie mille. Spiegazione molto chiara !!! –

1

Anche se la soluzione di @ Me.Name è completamente valida di per sé, c'è un trucco aggiuntivo che può tornare utile in alcune situazioni (lo ha fatto sicuramente per me): se stai convertendo più lambda usando questa tecnica , è possibile scomporre il cast come un metodo di supporto, lungo le linee di

object myDelegateToObject (Action<bool> action) { 
    return action; // autocast to `object` superclass, no explicit cast needed 
} 

e poi lo chiamano semplicemente

dict.Add("InProgress", myDelegateToObject(InProgress => base.InProgress = InProgress)); 

può risparmiare tempo in seguito - se si decide di cambiare per cambiare il segno atures, dovrai farlo in un solo posto.

3

ho ottenuto questo errore quando mi mancava

using System.Data.Entity; 
0

mi sono imbattuto in questo problema durante la scrittura di unit test. Stavo tentando di prendere in giro il comportamento di un database per restituire un nuovo oggetto da un repository invece di connettersi effettivamente a un database.

Assicurarsi che l'oggetto abbia un costruttore utilizzabile. Potrebbe non essere in grado di istanziare con successo quell'oggetto nel modo desiderato. Assicurati di utilizzare un lambda per indicare a un costruttore che il costruttore può essere chiamato nello stesso modo in una normale istanziazione.

cioè

return x => new FakeObject(); 

dire nel caso di

var fake = new FakeObject(); 

non avrebbe funzionato, allora lambda sarà anche fallire quindi state attenti.