roslyn CSharpScript 中的日期时间 returns 'expecting ;'
DateTime in roslyn CSharpScript returns 'expecting ;'
在 roslyn CSharpScript 求值器中使用 DateTime returns 错误代码 'Expected ;' 而字符串工作正常。
使用 Visual Studio 2019 与 Microsoft.CodeAnalysis.Common 和 Microsoft.CodeAnalysis.CSharp.Scripting 3.3.1
了解求值器需要配置,添加了 DateTime 程序集以及自定义 class 程序集。
public class Install
{
public int InstallId { get; set; }
public int RegistrationId { get; set; }
public int EnvironmentId { get; set; }
public DateTime SubmitDateTime { get; set; }
public string SubmitIdentity { get; set; }
public DateTime TargetDateTime { get; set; }
public string InstallerIdentity { get; set; }
public DateTime? StartDateTime { get; set; }
public DateTime? StopDateTime { get; set; }
public string Status { get; set; }
}
string queryText;
var fooFuture = DateTime.Now.AddDays(7);
var fooPast = DateTime.Now.AddDays(-7);
switch (TimeFrame)
{
case "future": // fails (expected) //
queryText = $"i => i.TargetDateTime < fooFuture";
break;
case "current": // works //
queryText = "i => i.Status == \"In Progress\"";
break;
case "past": // fails with interpolation -- expecting ; //
queryText = $"i => i.TargetDateTime > {fooPast}";
break;
default: // fails with DateTime -- expecting ; //
queryText = $"i => i.TargetDateTime < {DateTime.Now.AddDays(15)} && i.TargetDateTime > {DateTime.Now.AddDays(-15)}";
break;
}
ScriptOptions options = ScriptOptions.Default
.AddReferences(typeof(Install).Assembly)
.AddReferences(typeof(System.DateTime).Assembly);
Func<Install, bool> queryTextExpression = await CSharpScript.EvaluateAsync<Func<Install, bool>>(queryText, options);
无法理解为什么基本 DateTime 对象会导致问题。
字符串解析为 "i => i.TargetDateTime > 10/25/2019 11:00:00 AM"
。用引号引起来将其解释为字符串。
编辑:我应该补充一点,将字符串硬编码到上面的示例中也会失败并显示相同的错误消息,让我相信这是一个解析问题?不确定如何处理 DateTime 对象中的字符?
问题正如您所说 - 字符串正在解析为 "i => i.TargetDateTime > 10/25/2019 11:00:00 AM"
,这不是有效的 C# 代码。即使您添加了引号,也无法直接将 DateTime
与 string
进行比较
最终,您要么需要比较相同类型的对象。 string
到 string
、DateTime
到 DateTime
、long
到 long
等。我更喜欢将它们保留为 DateTime
对象。
因此,您需要在表达式的右侧构造一个DateTime
。
一种方法是使用 DateTime
构造函数,如下所示:
queryText = $"i => i.TargetDateTime > new System.DateTime({fooPast.Ticks}, System.DateTimeKind.{fooPast.Kind})";
另一个可以说更简洁的机制是通过内置的二进制序列化方法,它在一个值中同时考虑 Ticks
和 Kind
:
queryText = $"i => i.TargetDateTime > System.DateTime.FromBinary({fooPast.ToBinary()})";
在 roslyn CSharpScript 求值器中使用 DateTime returns 错误代码 'Expected ;' 而字符串工作正常。
使用 Visual Studio 2019 与 Microsoft.CodeAnalysis.Common 和 Microsoft.CodeAnalysis.CSharp.Scripting 3.3.1
了解求值器需要配置,添加了 DateTime 程序集以及自定义 class 程序集。
public class Install
{
public int InstallId { get; set; }
public int RegistrationId { get; set; }
public int EnvironmentId { get; set; }
public DateTime SubmitDateTime { get; set; }
public string SubmitIdentity { get; set; }
public DateTime TargetDateTime { get; set; }
public string InstallerIdentity { get; set; }
public DateTime? StartDateTime { get; set; }
public DateTime? StopDateTime { get; set; }
public string Status { get; set; }
}
string queryText;
var fooFuture = DateTime.Now.AddDays(7);
var fooPast = DateTime.Now.AddDays(-7);
switch (TimeFrame)
{
case "future": // fails (expected) //
queryText = $"i => i.TargetDateTime < fooFuture";
break;
case "current": // works //
queryText = "i => i.Status == \"In Progress\"";
break;
case "past": // fails with interpolation -- expecting ; //
queryText = $"i => i.TargetDateTime > {fooPast}";
break;
default: // fails with DateTime -- expecting ; //
queryText = $"i => i.TargetDateTime < {DateTime.Now.AddDays(15)} && i.TargetDateTime > {DateTime.Now.AddDays(-15)}";
break;
}
ScriptOptions options = ScriptOptions.Default
.AddReferences(typeof(Install).Assembly)
.AddReferences(typeof(System.DateTime).Assembly);
Func<Install, bool> queryTextExpression = await CSharpScript.EvaluateAsync<Func<Install, bool>>(queryText, options);
无法理解为什么基本 DateTime 对象会导致问题。
字符串解析为 "i => i.TargetDateTime > 10/25/2019 11:00:00 AM"
。用引号引起来将其解释为字符串。
编辑:我应该补充一点,将字符串硬编码到上面的示例中也会失败并显示相同的错误消息,让我相信这是一个解析问题?不确定如何处理 DateTime 对象中的字符?
问题正如您所说 - 字符串正在解析为 "i => i.TargetDateTime > 10/25/2019 11:00:00 AM"
,这不是有效的 C# 代码。即使您添加了引号,也无法直接将 DateTime
与 string
最终,您要么需要比较相同类型的对象。 string
到 string
、DateTime
到 DateTime
、long
到 long
等。我更喜欢将它们保留为 DateTime
对象。
因此,您需要在表达式的右侧构造一个DateTime
。
一种方法是使用 DateTime
构造函数,如下所示:
queryText = $"i => i.TargetDateTime > new System.DateTime({fooPast.Ticks}, System.DateTimeKind.{fooPast.Kind})";
另一个可以说更简洁的机制是通过内置的二进制序列化方法,它在一个值中同时考虑 Ticks
和 Kind
:
queryText = $"i => i.TargetDateTime > System.DateTime.FromBinary({fooPast.ToBinary()})";