Good day, the community!

Sorry for the name of the question, I just do not know how to conquer it. I had a need to ensure that the IronRuby and IronPython scripts can be executed in my program, m. I will add other languages, I do not know. Well, do not ask why I need it, that's all :)

And the task that I think is this: I found on the Internet a way to run interpreted languages ​​directly in a C # application, using the example of IronPython:

ScriptEngine engine = Python.CreateEngine(); ScriptScope scope = engine.CreateScope(); scope.SetVariable("y", yNumber); engine.ExecuteFile("D://hello2.py", scope); dynamic xNumber = scope.GetVariable("x"); dynamic zNumber = scope.GetVariable("z"); Console.WriteLine("Сумма {0} и {1} равна: {2}", xNumber, yNumber, zNumber); 

But in my program it is not known in advance what script will be used, so I want to replace

 ScriptEngine engine = Python.CreateEngine(); 

on something like

 ScriptEngine engine = EngineSelector.GetEngine(scriptExt).CreateEngine(); 

But how do I "save" the types? I can’t even imagine where to dig, and is it possible? I tried

 Dictionary<string, ScriptEngine> EngineSelector = new Dictionary<string, ScriptEngine>(); 

but failed. Thank you for reading though :)

UPD # 1 Error using Dictionary <>

https://yadi.sk/i/H-TQCdxStZe88

Error CS1061 'ScriptEngine' does not contain a definition for "CreateEngine" and could not find the extension method "CreateEngine", which accepts the type "ScriptEngine" as the first argument (possibly using the directive using or the link to the assembly).

UPD # 2

For Ruby, everything is also ScriptEngine engine = Ruby.CreateEngine (); You can do this:

 Dictionary<string, ScriptEngine> EngineSelector = new Dictionary<string, ScriptEngine>(); EngineSelector.Add(".py", Python.CreateEngine()); EngineSelector.Add(".rb", Ruby.CreateEngine()); 

But then, then Dictionary will already store objects that occupy memory, right?

UPD # 3

But is it effective?

  private void RunScript(string ScriptFilename) { Dictionary<string, ScriptEngine> EngineSelector = new Dictionary<string, ScriptEngine>(); EngineSelector.Add(".py", Python.CreateEngine()); EngineSelector.Add(".rb", Ruby.CreateEngine()); ScriptEngine engine = EngineSelector[Path.GetExtension(ScriptFilename)]; ScriptScope scope = engine.CreateScope(); engine.ExecuteFile(ScriptFilename, scope); } 
  • And why did not work? How did you try? Dictionary is the right solution. - VladD
  • VS reports an error to yadi.sk/i/H-TQCdxStZe88 'ScriptEngine "does not contain a definition for" CreateEngine "and could not find the extension method" CreateEngine "that takes the type of" ScriptEngine "as the first argument (perhaps the using directive or link to the assembly). - LukavskyM
  • Great, that's better. Now I think, as better. - VladD

1 answer 1

Try this:

 Dictionary<string, Func<ScriptEngine>> EngineSelector = new Dictionary<string, Func<ScriptEngine>>() { { ".py", Python.CreateEngine }, { ".rb", Ruby.CreateEngine } }; ScriptEngine engine = EngineSelector[".py"](); 
  • I did almost as well (added to the question). Here the pointer on function turns out is stored? Or how to say? - LukavskyM
  • one
    @ demol0cv: Yes, it’s like a function pointer (in C # this is called a delegate ). Thus you do not have in memory of the created object. - VladD pm
  • @ demol0cv: Well, it is a dictionary to create a dictionary once, at the beginning of the program, and not during the execution of each script. - VladD
  • Well, this function is only for tests, therefore the Dictionary is declared in her body - LukavskyM