0

Sometimes it's nice to be able to store lambda expressions somewhere that mean something in your business logic, for example

Expression<Func<Supplier,bool>> SupplierHasHighRating = x => x.Rating > 90;

This is like a lite form of the Specification Pattern. So you can do this:

var highRatedSuppliers = someQueryableOfSuppliers.Where(SupplierHasHighRating);

What I'd like to know if there is a way I can reuse the lambda in a query against a different object which is related to Supplier:

var productsOfHighRatedSuppliers = someQueryableOfProducts.Where(x => x.Supplier.Rating > 90);

Can I reuse the lambda here somehow?

Edit: If you believe the answer is yes, can you show how you would do it in terms of the above example?

David
  • 15,750
  • 22
  • 90
  • 150
  • Yes. You can do almost anything with expressions, but much of it isn't straight forward to most programmers. – N-ate Feb 08 '18 at 19:50
  • You could do this transparently by making an interface called ISupplierRating that requires a SupplierRating property or a GetSupplierRating method. Then apply the interface to both types. Finally use the interface in your stored Expression. – N-ate Feb 08 '18 at 19:55
  • @N-ate Thanks, I've edited the question above in response to your answer. – David Feb 08 '18 at 19:55
  • Another way you can do this is to make your expression use object and then it can apply to any collection. Inside the lambda do type checking. I personally dislike type checking objects, because it means you've lost design-time type checking. – N-ate Feb 08 '18 at 19:59
  • I'd like to be able to use the result in a database query too. I assume the type checking would rule that out... – David Feb 08 '18 at 20:11
  • It wouldn't rule it out, but type checking is terrible, because if you make a mistake you won't know until runtime. – N-ate Feb 09 '18 at 19:16

1 Answers1

-1

As people have pointed out: It is absolutely possible to do with expressions. However, in most realistic scenarios, the time it would take to create such functionality, would make it unfeasible. Taking all factors into account, for instance; performance might be an issue.

Creating an expression visitor takes time, dynamic expressions are hard, and if you aren't familiar with them, you're likely killing a few good hours before you get any actual work done. It's just … very unintuitive, if you've never tried it before.

There are other ways around this though; one approach is to simply use inheritance.

For instance, create a IRateable, which simply only exposes the property Rating. Then simply inherit it where needed.

As in your example:

public class Supplier : IRateable
{
  public int Rating { get; set; }
}

public class Product : IRateable
{
  // Get's the suppliers rating, tho, is this what you wanted?
  public int Rating => Supplier.Rating;

  public Supplier Supplier { get; set; }
}
mausworks
  • 1,607
  • 10
  • 23