Using Microsoft.CodeAnalysis.CSharp.Scripting I have created a generic method to turn a string into a predicate:
public static Func<T, bool> CreatePredicate<T>(string command)
{
var options = ScriptOptions.Default.AddReferences(typeof(T).Assembly);
Func<T, bool> predicate = CSharpScript.EvaluateAsync<Func<T, bool>>(command, options).Result;
return predicate;
}
The problem is that this is very slow. It takes 3-4 seconds to generate the predicate.
Is there a way to turn a string into a predicate faster using Roslyn? (I am aware of alternative of manually creating expression using Expression class, this question is specifically at doing this with Roslyn)
Here is stadalone example:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace DynamicLambda
{
class Program
{
static void Main(string[] args)
{
var albums = new List<Album>
{
new Album { Quantity = 10, Artist = "Betontod", Title = "Revolution" },
new Album { Quantity = 50, Artist = "The Dangerous Summer", Title = "The Dangerous Summer" },
new Album { Quantity = 200, Artist = "Depeche Mode", Title = "Spirit" },
};
var albumFilter = "album => album.Quantity > 20 && album.Quantity < 200";
var sw = new Stopwatch();
sw.Start();
var predicate = CreatePredicate<Album>(albumFilter);
sw.Stop();
var filteredAlbums = albums.Where(predicate).ToList();
}
public static Func<T, bool> CreatePredicate<T>(string command)
{
var options = ScriptOptions.Default.AddReferences(typeof(T).Assembly);
Func<T, bool> predicate = CSharpScript.EvaluateAsync<Func<T, bool>>(command, options).Result;
return predicate;
}
}
public class Album
{
public int Quantity { get; set; }
public string Title { get; set; }
public string Artist { get; set; }
}
}