2016-06-30 55 views
10

solito eseguo guardia controllando in questo modo:Guardia controllo di lambda

public void doStuff(Foo bar, Expression<Func<int, string>> pred) { 
    if (bar == null) throw new ArgumentNullException(); 
    if (pred == null) throw new ArgumentNullException(); 
    // etc... 
} 

Ho visto questo controllo supplementare che assicura che il predicato è in realtà un lambda:

if (pred.NodeType != ExpressionType.Lambda) throw new ArgumentException(); 

Il ExpressionType enum ha molte possibilità, ma non capisco come qualcuno di loro si applicherebbe perché ho pensato che il compilatore avrebbe permesso solo un lambda.

Q1: C'è un vantaggio? Facciamo un controllo accurato della guardia di tutti gli input, quindi questo aggiunge valore?

Q2: Esiste una penalità legata alle prestazioni, ovvero richiede più tempo rispetto a un normale controllo di tipo/limiti/null?

+0

Sembra che Q1 sia vantaggioso se si * desidera * assicurarsi che la propria espressione sia di un certo tipo, piuttosto che solo null controllarla. – Glubus

+0

@Glubus Potrebbe essere qualcosa di diverso da un lambda per cominciare? –

+0

Sì. Le espressioni sono usate per descrivere e usare i meta-dati dei dati che sta trattenendo. 'Espressione << Func >' descrive un delegato che accetta un intero e restituisce una stringa, ma in realtà non definisce un'istanza di questo delegato. In questo modo puoi creare interi alberi di espressioni concatenandoli insieme. Leggi l'articolo mdsn sulla classe Expression. – Glubus

risposta

3

Func<int, string> è un delegato che potrebbe essere l'indirizzo di una funzione o in linea come espressione lambda [() => x].

Expression<TDelegate> eredita dal LambdaExpression e la NodeType di un Expression<TDelegate> è sempre ExpressionType.Lambda.

Quindi, penso che tipo di codice difensivo non è necessaria.

+0

Sì, quello era il mio modo di pensare. Non vedo come possa essere qualcos'altro in questo caso. –