【发布时间】:2019-04-18 20:12:49
【问题描述】:
我正在尝试使用新的Roslyn 脚本模块。这是一个如何使用它的例子。请注意,Globals 似乎需要是 class。
public class Globals
{
public int X;
public int Y;
}
var globals = new Globals { X = 1, Y = 2 };
Console.WriteLine(await CSharpScript.EvaluateAsync<int>("X+Y", globals: globals));
我有一个generic function,它采用T 类型,数组的长度不确定(但在大多数情况下长度相对较小):
void Func<T>()
{
T[] values;
}
如何将T[] 转换为anonymous type?
所以如果我有T 如果类型为decimal 并且在这种情况下values 的长度为3,
values[0] = 124.3, values[1] = 132.4, values[2] = 23
我想创建一个看起来像这样的anonymous type:
var v = new { v1 = 124.3, v2 = 232.4, v3 = 23 };
这可能吗?也就是说,要从编译时不知道长度的数组创建匿名类型?
注意:这就是为什么我需要匿名类型而不是元组或 List 等的原因。而且,由于我不知道数组有多大,所以我不能硬连线一个类强>
编辑 1
当我尝试下面给出的甚至编译的解决方案时,我有点震惊:
dynamic v = new ExpandoObject();
var dictionary = (IDictionary<string, object>)v;
dictionary.Add("X", 1.5);
dictionary.Add("Y", 2.7);
//var globals = new Globals { X = 1.5, Y = 2.7 };
var retval = CSharpScript.EvaluateAsync<double>("System.Math.Sqrt(System.Math.Log(X + Y))",
globals: dictionary).GetAwaiter();
//retval = (decimal)Convert.ChangeType(retval, typeof(decimal));
Console.WriteLine(retval.GetResult());
很遗憾,我收到了运行时错误:
Microsoft.CodeAnalysis.Scripting.CompilationErrorException
HResult=0x80131500
Message=(1,34): error CS0103: The name 'X' does not exist in the current context
Source=Microsoft.CodeAnalysis.Scripting
StackTrace:
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter)
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, Boolean emitDebugInformation, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync[T](String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync[T](String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken)
at Trady.Form1.InitializeScriptEngineAsync() in C:\Users\idf\Form1.cs:line 79
at Form1..ctor() in C:\Users\idf\Form1.cs:line 56
at Trady.Program.Main() in C:\Users\idf\Program.cs:line 19
【问题讨论】:
-
索引与我无关。只是解决方案。
-
你考虑过
List<T>吗? -
查看编辑后的帖子了解为什么我需要匿名类型。
-
为什么数组本身不能是“全局”包装器上的命名属性,例如:
CSharpScript.EvaluateAsync<int>("v[0]+v[1]", globals: new { v = new [] { 1, 2 }}).GetAwaiter()? -
github.com/dotnet/roslyn/wiki/Scripting-API-Samples#chain 对你有用吗(如果你只有简单的值可能没问题)...否则可能与 stackoverflow.com/questions/3862226/… 重复
标签: c# anonymous-types c#-7.0