我有以下脚本来调用CSharpScript引擎;
https://blog.jayway.com/2015/05/09/using-roslyn-to-build-a-simple-c-interactive-script-engine/
我有一个命名空间Test:
namespace Test {
class B() {
}
}
我添加了CSharpScriptEngine的选项;
options = ScriptOptions.Default
.WithReferences(Assembly.GetExecutingAssembly())
.AddImports("Test")
现在我执行以下代码:
class A {}
var a1 = new A();
var a2 = new A();
a1==a2
False
这是正确的,现在:
var b1 = new B();
var b2 = new B();
b1 == b2
Error in code 'b1 == b2': Operator '==' cannot be applied to operands of type 'B' and 'B'
b1.GetType()==b2.GetType()
True
使用任何外部类,我无法获得在CSharpScript引擎中创建的两个实例,这些实例被C#视为具有相同的类型。
Edit3,另一个可爱的例子:
> string Hello(B world) { return world.ToString(); }
> Hello(new B())
Error in code 'Hello(new B())': Argument 1 cannot convert from 'Test.B [C \Users\User\Projects\Test\bin\Debug\netcoreapp2.0\Test.dll]' to 'Test.B [Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]'
Edit1,格式化评论答案:
> var b1 = new B();
> var b2 = new B();
> b1.GetType().AssemblyQualifiedName
Test.B, Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
> b2.GetType().AssemblyQualifiedName
Test.B, Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
> b1==b2
Error in code 'b1==b2': Operator '==' cannot be applied to operands of type 'B' and 'B'
Edit2,使用完整命名空间评论答案:
> new B() == new B()
False
> new Test.B() == new Test.B()
False
> var b1 = new Test.B();
> var b2 = new Test.B();
> b1==b2
Error in code 'b1==b2': Operator '==' cannot be applied to operands of type 'B' and 'B'
Edit4,使用相同代码的失败和后续示例重现的格式化代码:
using System;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Scripting;
namespace Test
{
public class B
{
}
public class CSharpScriptEngine
{
private static ScriptState<object> scriptState = null;
static ScriptOptions options;
public static void Init()
{
options = ScriptOptions.Default
.WithReferences(Assembly.GetExecutingAssembly())
.AddImports("Test")
;
}
public static object Execute(string code)
{
try
{
scriptState = scriptState == null
? CSharpScript.RunAsync(code, options).Result
: scriptState.ContinueWithAsync(code, options).Result;
if (scriptState.ReturnValue != null
&& !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
{
return scriptState.ReturnValue;
}
}
catch (Exception e)
{
string str = e.Message;
if (str.Contains(": error CS"))
{
str = string.Join(' ', str.Split(':').Skip(2).ToArray());
}
System.Console.WriteLine($"Error in code '{code}': {str}");
}
return null;
}
}
class Program
{
static void Main(string[] args)
{
CSharpScriptEngine.Init();
var code = @"
var b1 = new B();
var b2 = new B();
b1 == b2
";
// -> SUCCEEDS!
Console.WriteLine(CSharpScriptEngine.Execute(code)?.ToString());
// -> FAILS!
code.Split('\n').Select(s => CSharpScriptEngine.Execute(s)).Where(s => s != null).ToList().ForEach(s => Console.WriteLine(s));
Console.ReadLine();
}
}
}