3

I am having problems getting this code to work. It seems that the CSharpScript.EvaluateAsync will not understand the Linq 'Select' command even though I think I am adding the proper references to the ScriptOptions. The goal here is to use the EvaluateAsync to run string based Linq queries. Thanks for your assistance in advance.

List<Dog> dogs = new List<Dog>();

dogs.Add(new Dog()
{ Name = "spike", Breed = "Poodle" });

dogs.Add(new Dog()
{ Name = "george", Breed = "Spaniel" });

dogs.Add(new Dog()
{ Name = "sammy", Breed = "Weimaraner" });


Console.WriteLine("Analyzing List");

// Func to return max string length of Breed Property in list of Dogs
int maxlen = dogs.Select(d => d.Breed.Trim().Length).OrderByDescending(d1 => d1).First();



// Recreated Func using Microsoft.CodeAnalysis.CSharp.Scripting.
var myLambda = "d => d.Select(d => d.Breed.Trim().Length).OrderByDescending(d1 => d1).First()";

Assembly[] assemblies = {
    typeof(Dog).Assembly,
    System.Reflection.Assembly.Load("System.Collections"),
    System.Reflection.Assembly.Load("System.Linq"),
    System.Reflection.Assembly.GetExecutingAssembly()
    
};

ScriptOptions options = ScriptOptions.Default.AddReferences(
             assemblies
            );

Func<List<Dog>, int> Dexprssn = await CSharpScript.EvaluateAsync<Func<List<Dog>, int>>(myLambda, options);
/*
   Error
        Microsoft.CodeAnalysis.Scripting.CompilationErrorException
        HResult=0x80131500
        Message=(1,8): error CS1061: 'Dog' does not contain a definition for 'Select' and no accessible 
            extension method 'Select' accepting a first argument of type 'Dog' could be found 
            (are you missing a using directive or an assembly reference?)
 */
ChiliYago
  • 11,341
  • 23
  • 79
  • 126
  • 1
    What happens if you use a traditional static call instead of an extension-method syntax? e.g. `d => Enumerable.OrderByDescending( Enumerable.Select( d1, d1 => d1.Breed.Trim().Length )..., etc )`. – Dai Oct 24 '20 at 18:12
  • Also, reusing the same lexical name for a variable (as you're doing in your code: `d` is two things) is not a good idea. – Dai Oct 24 '20 at 18:13
  • i updated the lexical name – ChiliYago Oct 24 '20 at 18:29
  • Not sure I understand how to update my code to static calls. – ChiliYago Oct 24 '20 at 18:30

1 Answers1

4

Adding assemblies as references is one part of it but to add any 'using directives' then you should also use AddImports():

//..

ScriptOptions options = ScriptOptions.Default.AddReferences(assemblies);

options = options.AddImports("System.Linq");

//..
Ray
  • 187,153
  • 97
  • 222
  • 204