2016-06-30 14 views
10

zwykle wykonać osłonę sprawdzenie tak:Straż sprawdzanie lambdas

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

Widziałem tę dodatkową kontrolę, która gwarantuje, że orzeczenie jest faktycznie lambda:

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

ExpressionType enum ma wiele możliwości, ale nie rozumiem, jak którykolwiek z nich miałby zastosowanie, ponieważ założyłem, że kompilator zezwala tylko na lambdę.

Q1: Czy jest to korzystne? Dokładnie sprawdzamy wszystkie wejścia, więc czy to dodaje wartości?

Q2: Czy jest kara za wydajność - np. Czy trwa dłużej niż zwykłe sprawdzanie typu/granice/zero?

+0

Wydaje się, że Q1 przynosi ci korzyści, jeśli * chcesz *, aby upewnić się, że twoje wyrażenie jest określonego typu, a nie tylko zerowe sprawdzanie. – Glubus

+0

@Glubus Czy jednak może być coś innego niż lambda? –

+0

Tak. Wyrażenia służą do opisywania i używania metadanych danych, które przechowują. 'Wyrażenie << Func >' opisuje delegata, który akceptuje liczbę całkowitą i zwraca ciąg, ale nie definiuje faktycznie instancji tego delegata. W ten sposób możesz tworzyć całe drzewa wyrażeń, łącząc je ze sobą. Sprawdź artykuł mdsn dotyczący klasy Expression. – Glubus

Odpowiedz

3

Func<int, string> jest delegatem, który może być adresem funkcji lub wbudowanym wyrażeniem lambda [() => x].

Expression<TDelegate> dziedziczy z LambdaExpression i NodeType o Expression<TDelegate> jest zawsze ExpressionType.Lambda.

Tak, myślę, że rodzaj kodu obronnej nie jest potrzebne.

+0

Tak, to było moje myślenie. Nie widzę, jak może to być cokolwiek innego w tym przypadku. –