11

I usually perform guard checking like so:

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

I've seen this extra check which ensures that the predicate is actually a lambda:

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

The ExpressionType enum has many possibilities, but I don't understand how any of them would apply because I assumed the compiler would only allow a lambda.

Q1: Is there benefit to this? We do thorough guard checking of all inputs, so does this add value?

Q2: Is there a performance penalty - i.e. does it take longer than a regular type/bounds/null check?

h bob
  • 3,610
  • 3
  • 35
  • 51
  • Seems that Q1 benefits you if you *want* to make sure that your expression is of a certain type, rather than just null checking it. – Glubus Jun 30 '16 at 08:56
  • @Glubus Could it be anything other than a lambda to begin with though? – h bob Jun 30 '16 at 08:59
  • Yes. Expressions are used to describe and use the meta-data of the data it is holding. `Expression<>` describes a delegate that accepts an integer and returns a string, but does not actually define an instance of this delegate. This way you can create entire expression tree's by chaining them together. Checkout the mdsn article about the Expression class. – Glubus Jun 30 '16 at 09:12
  • @Glubus what do you think of answer by jlvaquero – h bob Jun 30 '16 at 09:23
  • 2
    It's correct, since your parameter is of type `Expression>`, `pred` will always be `Expression.Lambda`. I probably made this confusing because I thought for a while you were talking about the `Expression` class in general. – Glubus Jun 30 '16 at 09:36

1 Answers1

4

Func<int, string> is a delegate that could be the address of a function or inline as lambda expression [ () => x ] .

Expression<TDelegate> inherits from LambdaExpression and the NodeType of an Expression<TDelegate> is always ExpressionType.Lambda.

So, I think that kind of defensive code is not needed.

jlvaquero
  • 8,571
  • 1
  • 29
  • 45