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# 代码。即使您添加了引号,也无法直接将 DateTimestring

进行比较

最终,您要么需要比较相同类型的对象。 stringstringDateTimeDateTimelonglong 等。我更喜欢将它们保留为 DateTime对象。

因此,您需要在表达式的右侧构造一个DateTime

一种方法是使用 DateTime 构造函数,如下所示:

queryText = $"i => i.TargetDateTime > new System.DateTime({fooPast.Ticks}, System.DateTimeKind.{fooPast.Kind})";

另一个可以说更简洁的机制是通过内置的二进制序列化方法,它在一个值中同时考虑 TicksKind

queryText = $"i => i.TargetDateTime > System.DateTime.FromBinary({fooPast.ToBinary()})";