✅ How to correctly write conditions with expressions?
I have this code:
everything is ok but i would like to know is it possible to write smth like this?
public static class BookPolicy
{
public static void AllowRead(Book book)
{
var isHorrorBook = Specifications.IsHorrorBook().Compile();
var isPonyBook = Specifications.IsPonyBook().Compile();
if (isHorrorBook(book) || isPonyBook(book))
throw new Exception("Horror or pony books don't allow here");
}
}
public static class Specifications
{
public static Expression<Func<Book, bool>> IsHorrorBook() =>
book => book.Title.Contains("Frankenstein");
public static Expression<Func<Book, bool>> IsPonyBook() =>
book => book.Title.Contains("Pony");
}
public static class BookPolicy
{
public static void AllowRead(Book book)
{
var isHorrorBook = Specifications.IsHorrorBook().Compile();
var isPonyBook = Specifications.IsPonyBook().Compile();
if (isHorrorBook(book) || isPonyBook(book))
throw new Exception("Horror or pony books don't allow here");
}
}
public static class Specifications
{
public static Expression<Func<Book, bool>> IsHorrorBook() =>
book => book.Title.Contains("Frankenstein");
public static Expression<Func<Book, bool>> IsPonyBook() =>
book => book.Title.Contains("Pony");
}
if(book is Horror or Pony) {...}
I don't understand how to do this with expressions2 Replies
yes
Well, not exactly
But similar
I think you can do
chatgpt at work (it's just tedious to write out manually)
also fyi they aren't cached
the whole tree gets recreated each time you call that method
make it a readonly field for it to get cached
(book.GetType() == typeof(Horror) || book.GetType() == typeof(Pony)) ? DoStuff1() : DoStuff2()
(book.GetType() == typeof(Horror) || book.GetType() == typeof(Pony)) ? DoStuff1() : DoStuff2()
using System;
using System.Linq.Expressions;
public class Book { }
public class Horror : Book { }
public class Pony : Book { }
public class Program
{
public static void Main()
{
// Assuming these are the provided expressions
Expression<Func<Book, bool>> isHorror = book => book.GetType() == typeof(Horror);
Expression<Func<Book, bool>> isPony = book => book.GetType() == typeof(Pony);
ParameterExpression bookParam = isHorror.Parameters[0];
var parameterReplacer = new ParameterReplacer(bookParam);
Expression isPonyReplaced = parameterReplacer.Visit(isPony.Body);
Expression combinedCondition = Expression.OrElse(isHorror.Body, isPonyReplaced);
MethodCallExpression doStuff1Call = Expression.Call(typeof(Program).GetMethod(nameof(DoStuff1)));
MethodCallExpression doStuff2Call = Expression.Call(typeof(Program).GetMethod(nameof(DoStuff2)));
Expression ternaryExpression = Expression.Condition(combinedCondition, doStuff1Call, doStuff2Call);
var lambda = Expression.Lambda<Action<Book>>(ternaryExpression, bookParam);
}
public static void DoStuff1()
{
Console.WriteLine("DoStuff1 called");
}
public static void DoStuff2()
{
Console.WriteLine("DoStuff2 called");
}
// Helper class to replace parameters in an expression
private class ParameterReplacer : ExpressionVisitor
{
private readonly ParameterExpression _parameter;
public ParameterReplacer(ParameterExpression parameter)
{
_parameter = parameter;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return _parameter; // Replace with the correct parameter
}
}
}
using System;
using System.Linq.Expressions;
public class Book { }
public class Horror : Book { }
public class Pony : Book { }
public class Program
{
public static void Main()
{
// Assuming these are the provided expressions
Expression<Func<Book, bool>> isHorror = book => book.GetType() == typeof(Horror);
Expression<Func<Book, bool>> isPony = book => book.GetType() == typeof(Pony);
ParameterExpression bookParam = isHorror.Parameters[0];
var parameterReplacer = new ParameterReplacer(bookParam);
Expression isPonyReplaced = parameterReplacer.Visit(isPony.Body);
Expression combinedCondition = Expression.OrElse(isHorror.Body, isPonyReplaced);
MethodCallExpression doStuff1Call = Expression.Call(typeof(Program).GetMethod(nameof(DoStuff1)));
MethodCallExpression doStuff2Call = Expression.Call(typeof(Program).GetMethod(nameof(DoStuff2)));
Expression ternaryExpression = Expression.Condition(combinedCondition, doStuff1Call, doStuff2Call);
var lambda = Expression.Lambda<Action<Book>>(ternaryExpression, bookParam);
}
public static void DoStuff1()
{
Console.WriteLine("DoStuff1 called");
}
public static void DoStuff2()
{
Console.WriteLine("DoStuff2 called");
}
// Helper class to replace parameters in an expression
private class ParameterReplacer : ExpressionVisitor
{
private readonly ParameterExpression _parameter;
public ParameterReplacer(ParameterExpression parameter)
{
_parameter = parameter;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return _parameter; // Replace with the correct parameter
}
}
}
ah thanks for helping me