如何将对象传递给脚本?

时间:2016-07-09 05:28:04

标签: 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);

1 个答案:

答案 0 :(得分:7)

Globals类型应该包含任何全局变量声明作为它的属性。

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

var metadata = MetadataReference.CreateFromFile(typeof(MyClass).Assembly.Location);

选项1

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

public class Globals
{
    public MyClass C { get; set; }
}

并将其用作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;

请注意,在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 });

选项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);