如何将对象传递给脚本?

Iva*_*ono 4 c# roslyn

在以下代码段中,如何将对象作为参数传递给脚本中的方法?

var c = new MyAssembly.MyClass()
{
    Description = "test"
};

var code = "using MyAssembly;" +
           "public class TestClass {" +
           "  public bool HelloWorld(MyClass c) {" +
           "    return c == null;" +
           "  }" +
           "}";

var script = CSharpScript.Create(code, options, typeof(MyAssembly.MyClass));
var call = await script.ContinueWith<int>("new TestClass().HelloWorld()", options).RunAsync(c);
Run Code Online (Sandbox Code Playgroud)

kro*_*nis 7

Globals类型应包含所有全局变量声明作为其属性。

假设您对脚本有正确的引用:

var metadata = MetadataReference.CreateFromFile(typeof(MyClass).Assembly.Location);
Run Code Online (Sandbox Code Playgroud)

选项1

您需要定义一个MyClass类型的全局变量:

public class Globals
{
    public MyClass C { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并将其用作Globals类型:

var script = 
    await CSharpScript.Create(
        code: code,
        options: ScriptOptions.Default.WithReferences(metadata),
        globalsType: typeof(Globals))
    .ContinueWith("new TestClass().HelloWorld(C)")
    .RunAsync(new Globals { C = c });

var output = script.ReturnValue;
Run Code Online (Sandbox Code Playgroud)

请注意,在ContinueWith表达式中,既是C变量又是C属性Globals。这应该够了吧。


选项2

在您的情况下,如果您打算多次调用脚本,则创建一个委托可能是有意义的:

var f =
    CSharpScript.Create(
        code: code,
        options: ScriptOptions.Default.WithReferences(metadata),
        globalsType: typeof(Globals))
    .ContinueWith("new TestClass().HelloWorld(C)")
    .CreateDelegate();

var output = await f(new Globals { C = c });
Run Code Online (Sandbox Code Playgroud)

选项3

就您而言,您甚至不需要通过任何 Globals

var f =
    await CSharpScript.Create(
        code: code,
        options: ScriptOptions.Default.WithReferences(metadata))
    .ContinueWith<Func<MyClass, bool>>("new TestClass().HelloWorld")
    .CreateDelegate()
    .Invoke();

var output = f(c);
Run Code Online (Sandbox Code Playgroud)