Hi I want to use Roslyn to scripting in my app. But I have new (September) version and I am confused. I want to execute file with some simply function.
For example:
public int m(){
return 6;
}
I found some articles about it for example acticle. There is some way to do it, but in my version isn't Session.Create()
I want to use it like IronPython scripting
Something like:
var scriptEngine = new SciptEngine.ExecuteFile(fileWithFunction);
dynamic d = getFunction(m);
or
dynamic d = callFunction(m);
Is it possible or I must use IronPython scripting?
The API hasn't changed significantly since the original CTP that the article was written in. For your scenario:
var scriptEngine = new ScriptEngine();
var session = scriptEngine.CreateSession();
session.AddReference("System");
session.AddReference("System.Core");
session.Execute(#"public int m() { return 6; }");
int six = session.Execute<int>("m()");
Related
I am working on a project that uses Javascript.net (formerly Noesis Javascript .net) as a scripting engine.
How do you add a C# method to the global context in Javascript?
For example, say I have in C#:
public int Foo(int bar)
{
return bar * 2;
}
I want to be able to call in Javascript:
var x = 5;
var y = Foo(x); // y is now 10;
In other libraries such as Jurassic this is possible:
engine.SetGlobalFunction("Foo", new Func<int, int>((a) => a*2));
This example comes from the unit tests:
_context.SetParameter("f", new Func<string,string>((s) => s.ToUpper()));
_context.Run("f('Noesis') == 'NOESIS'").Should().BeOfType<bool>().Which.Should().BeTrue();
I have a load of data files in numpy .npz format written from python.
I want to read them directly into C# for a few reasons.
The data files contain a number of 1D arrays of different types - some will by byte arrays, and other double arrays.
Can anyone give me some advice on how to achieve this? Or otherwise what I might be doing wrong below?
I have tried using Accord.NET.NPZFormat but can't figure out how to make it work. I think probably because you have to give it a type to return, and because the arrays are of different types it fails.
Here is a link to it:
http://accord-framework.net/docs/html/M_Accord_IO_NpzFormat_Load__1.htm
I am struggling with syntax here, unsure of what to use as "T". The closest I have got is with the following, but doesn't seem to have any data in the result. Accord.IO has no example code.
public static void LoadNPZ(string zip_file, string npz_file)
{
byte[] ret = new byte[0];
using (ZipArchive zip = ZipFile.OpenRead(zip_file))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
if (entry.Name == npz_file + ".npz")
{
Stream fs = entry.Open();
ret = new byte[fs.Length];
fs.Read(ret, 0, (int)fs.Length);
}
}
}
if (ret.Length==0)
{
return;
}
var ret2 = NpzFormat.Load<object[]>(ret);
};
You can use the NumSharp library.
Let say you have this data created in Python.
import numpy as np
arr = np.array([1,2,3,4])
single = arr.astype(np.single)
double = arr.astype(np.double)
np.savez('single.npz', data=single)
np.savez('double.npz', data=double)
The C# code to read them is below.
using NumSharp;
var singleContent = np.Load_Npz<float[]>("single.npz"); // type is NpzDictionary
var singleArray = singleContent["data.npy"]; // type is float[]
var doubleContent = np.Load_Npz<double[]>("double.npz"); // type is NpzDictionary
var doubleArray = doubleContent["data.npy"]; // type is double[]
If you don't specify name for your array then the default name is arr_0, and the C# code would be like this.
var singleArray = singleContent["arr_0.npy"];
var doubleArray = doubleContent["arr_0.npy"];
Note that NumSharp has the following limitation.
The size of each dimension must be smaller than 2,147,483,591 bytes. Example: for integer (4 bytes), each dimension must have less than 536,870,898 elements.
If you are using .NET Framework, the maximum array size is 2GB (all dimensions considered). On 64-bit platform this limit can be avoided by enabling the gcAllowVeryLargeObjects flag.
More information can be found in this answer and this blog post (Disclaimer: I'm the author of both of them).
I work with C# and python quite a bit, and my reccomendation is to create a COM Server
http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartServerCom.html
then in python you could simply have something like
import numpy as np
class NPtoCSharp:
_reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"
_public_methods_ = ['load_file']
_public_attrs_ = ['arr', 'the_file']
_reg_desc_ = "Python NPZ Loader"
_reg_progid_ = "NPtoCSharp"
def __init__(self):
self.arr = None
self.the_file = None
def load_file(self):
self.arr = np.load(self.the_file)
return self.arr
Then in C#
public void init_python()
{
Type NPtoCSharp = Type.GetTypeFromProgID("NPtoCSharp");
NPtoCSharpInst = Activator.CreateInstance(NPtoCSharp);
NPtoCSharpInst.the_file = 'myfile.npz';
}
Not complete but I hope you get the idea.
I'm currently working on a game (console application) with 25 Chunks, that are 5x5. All Chunks are in a List(5x5) witch is the Level in the end.
I do not want to declare all arrays. I would like to write a method in witch the arrays will be declared but with changing names.
For example:
- ac_Array_1
- ac_Array_2
static void Level()
{
List<char[,]> ol_Level = new List<char[,]>();
}
static void Spielblock()
{
int i_Stelle = 1;
string s_ArrayName = "ac_Chunk_" + i_Stelle;
i_Stelle++;
char[,] /*NAME*/ = new char[5, 5];
}
Try something like this:
int numOfLevels = 5;
Dictionary<string, char[,]> ol_Level = Enumerable
.Range(1, numOfLevels)
.ToDictionary(k => $"ac_Chunk_{k}", v => new char[5,5]);
ac_Chunk = ol_Level["ac_Chunk_1"];//char[5,5]
for (int i_Row = 0; i_Row < ac_Chunk.getLength(0); i_Row++)
{
for (int i_column = 0; i_column < ac_Chunk.getLength(1); i_column++)
{
ac_Chunk[i_Row, i_column] = '#';
}
}
...
levels:
ac_Chunk_1, ac_Chunk_2, ac_Chunk_3, ac_Chunk_4, ac_Chunk_5
n.b. using System.Linq and c# 6.0 $ interpolation
To have a dynamic variable name like you are requesting is not a simple thing to accomplish.
Generally, variable names are known at compile time, and the compiler can make optimizations using that information. What you are requesting would keep that from happening.
So the suggestions that you are seeing: create a variable, such as a dictionary, known when compiling and writing the code. Make that variable one that can dynamically expand to contain as many "chunks" as you'd like. And with a Dictionary<string, char[,]> you can even give each of those chunks a name. They won't be individual variable names, but it will let you access them by string/name and iterate through the collection in different ways.
To add a detail to Johnny's answer, at any point you can use
var ac_chunk = ol_Level["ac_Chunk_1"];
if you want to repeatedly access an individual chunk.
Or, even easier, just keep using ol_Level[$"ac_Chunk_{chunkNumber}"]
I'm trying to write simple automation test using TestComplete in C#.
(Not JScript/C# Script, just C#)
I'm using their libraries as you can see here:
https://support.smartbear.com/viewarticle/74747/
and specifically their 'var' type: https://support.smartbear.com/viewarticle/68791/
I'm trying to identify all the elements on the screen according to specific key and value, using the method "FindAll" (https://support.smartbear.com/viewarticle/71244/)
var a = someProcess["FindAll"]("text", "Simulate", 200, false);
In debug mode I can see that "a" has two encapsulated elements that he found and this line passes successfully.
The problem: I'm trying to get the first element, using the line
var b = a["0"];
and get a 'MissingMethodException'.
If I try to use
var b = a(0);
it says I'm trying to use variable as a function.
I couldn't find any method that can help me to get the elements.
Here is how you can process such an array in C#:
var font = Connect.Sys["Process"]("notepad")["Window"]("#32770", "Font", 1);
var a = font["FindAllChildren"]("WndClass", "ComboBox");
object[] elements = (a.UnWrap() as object[]);
for (int i = 0; i < elements.Count(); i++) {
var element = new var(elements[i]);
MessageBox.Show(element["FullName"].UnWrap() as string);
}
I am guessing it neither invokes csc.exe or implement an entire compiler, so how does it work?
Update: Thanks to Jon Skeet for the pointer to code that was easy to learn from.
string c = #"
public class A
{
public static void Main(string[] args)
{
System.Console.WriteLine(""hello world"");
}
}
";
CodeDomProvider compiler = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.WarningLevel = 4;
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
CompilerResults r = compiler.CompileAssemblyFromSource(parameters, c);
Assembly a = r.CompiledAssembly;
Type[] ts = a.GetTypes();
Type t = ts[0];
object o = t.GetMethod("Main").Invoke(null, new object[] { new string[] { } });
From "How LINQPad Works":
LINQPad compiles your queries using .NET's CSharpCodeProvider (or VBCodeProvider)
Obviously there's rather more to it, but that's the bit you asked about - read the link for more details.
If you want to have a look at a rather more simplistic implementation, you could download the source code for Snippy, the little tool I created for C# in Depth. Again, it uses CSharpCodeProvider - and it's a simple enough example that it's easy to understand, with any luck. (There are only a few classes involved, IIRC.)
Jon's answer from almost 5 years ago is now out of date.
From "How LINQPad Works" (as at 29 Jan 2016):
LINQPad 5 compiles your queries using the Microsoft Roslyn libraries
(in the past it used .NET's CSharpCodeProvider and VBCodeProvider).
You can see an example of how to use Roslyn to compile your code here:
Learn Roslyn Now - Part 16 - The Emit API