2015-06-27 14 views
12

Strano comportamento di DLR. Ho un metodo accetta due argomenti: dinamico e Func <>. Quando passo solo OR dinamico solo Func <> - nessun errore. Ma quando provo a passare questi argomenti allo stesso tempo - appare l'errore "Impossibile utilizzare un'espressione lambda come argomento di un modo dinamico spedito un'operazione senza prima lanciare ad un delegato o un'espressione di tipo albero".:Impossibile passare l'argomento dinamico e lambda al metodo

static void Main(string[] args) 
    { 
     dynamic d = 1; 

     Method1(d);// - OK 
     Method2(f => 1);// - OK 
     Method3(d, f => 1);// - Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type. 
    } 

    static void Method1(dynamic d) 
    { 
    } 

    static void Method2(Func<string, int> func) 
    { 
    } 

    static void Method3(dynamic d, Func<string, int> func) 
    { 
    } 

Perché succede?

Naturalmente posso fare cast esplicito, e l'errore andare via:

Method3(d, (Func<string, int>)(f => 1)); 

Ma è a disagio. Il compilatore conosce il tipo di lambda, perché richiede il casting?

+0

Non è una risposta, ma una piccola ricerca su questo argomento http://weblogs.asp.net/davidfowler/dynamic-linq-a-little-more-dynamic –

+0

possibile duplicato di [C# - Passaggio di una funzione anonima come un parametro] (http://stackoverflow.com/questions/10899761/c-sharp-passing-an-anonymous-function-as-a-parameter) –

+0

se è scomodo Puoi digitare 'Method3 ((int) d, f => 1); '. e funziona. ho cancellato la mia risposta perché anch'io mi sono confuso! su quello che hai detto. ma malato ti faccio sapere se trovo quello che sta realmente accadendo. come mai dovresti sapere che il tipo di 'f => 1' non è noto fino a quando non viene specificato da te o dai parametri del metodo. –

risposta

6

Abbiamo fatto qualche ricerca e letto alcune delle IL generate dal compilatore per ognuno dei vostri casi.

Questo sembra essere un limite nella flessibilità della compilazione dinamica. Poiché il tuo metodo utilizza un parametro dinamico, l'intera chiamata diventa ora un'operazione dinamica. Ciò significa che tutti i parametri sono in ritardo, quindi l'elaborazione dei parametri passa attraverso un percorso di elaborazione diverso durante la compilazione rispetto ai parametri che non partecipano a un'operazione dinamica.

Chiaramente, come dimostra la tua chiamata a Method2, il compilatore ha la capacità di dedurre che l'intento è che f => 1 sia trattato come una stringa <, int >.

Tuttavia, sembra che questa funzionalità, probabilmente a causa della complessità della creazione del sito di chiamata dinamico, non sia ancora supportata nella compilazione dinamica.

Questo è uno di quei casi in cui Microsoft non supporta ancora una funzionalità, ma potrebbe aggiungerla in futuro.

Per ora sembra che tu non abbia altra scelta che dare un suggerimento al compilatore.

Problemi correlati