【问题标题】:DateTime in roslyn CSharpScript returns 'expecting ;'roslyn CSharpScript 中的 DateTime 返回 'expecting ;'
【发布时间】:2019-10-25 18:09:54
【问题描述】:

在 roslyn CSharpScript 评估程序中使用 DateTime 返回错误代码“预期;”而字符串工作正常。

将 Visual Studio 2019 与 Microsoft.CodeAnalysis.Common 和 Microsoft.CodeAnalysis.CSharp.Scripting 3.3.1 结合使用

了解评估器需要配置,添加了 DateTime 程序集以及自定义类程序集。

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 =&gt; i.TargetDateTime &gt; 10/25/2019 11:00:00 AM"。用引号括起来会导致它被解释为字符串。

编辑:我应该在上面的示例中添加硬编码字符串也会失败并显示相同的错误消息,让我相信这是一个解析问题?不知道如何处理 DateTime 对象中的字符?

【问题讨论】:

  • 为什么投反对票?真的,请提供解释,以便我将来可以更好地起草问题。不要只是向下箭头和螺栓。这有什么帮助?
  • 您希望在这里发生什么?您正在使用 string 插值,它在传递给它的对象上调用 ToString()。如您所见,在DateTime 的情况下,您会得到一个日期字符串。
  • @Herohtar - 这并不是一个坏问题。将鼠标悬停在 upvote/downvote 按钮上以阅读工具提示。这个问题是否符合展示研究、清晰和有用的标准?我认为是的。
  • 如果您在每种情况下检查 queryText 获取的值,我希望在调试器中很容易发现此问题的原因。我没有投反对票,但我可以看到有人看到这个问题并认为“他没有尝试调试它。”
  • @MattJohnson-Pint 问题本质上是“为什么评估 i.TargetDateTime &gt; 10/25/2019 11:00:00 AM 会导致错误?”。这是一个好问题吗?这显然不是一个有效的 C# 语句。

标签: c# roslyn csharpscript


【解决方案1】:

问题如您所说 - 字符串解析为 "i =&gt; i.TargetDateTime &gt; 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()})";

【讨论】:

  • 我尝试了 Matt 发布的 Binary 解决方案:{"(1,45): error CS0426: The type name 'FromBinary' doesn't exist in the type 'DateTime'"} 将尝试第一个变体.谢谢。
  • @Badchenn 你用的是什么平台? .Net 框架? .Net 核心? .Net 标准?什么版本?这种方法确实存在。
  • DOTNETCORE 3.0 正常。发现在字符串中调用 .ToBinary 是不可接受的。但是,我很容易在上面的变量声明中调用它。所以变量 fooPast 不是二进制的。但是,编译再次失败:queryText "i => i.Status \"Complete\" && i.TargetDateTime > new System.DateTime.FromBinary(-8586301823432291125)" ERROR: + ex {"(1,15): error CS1002: ; 预期"} Microsoft.CodeAnalysis.Scripting.CompilationErrorException
  • @Badchenn i.Status \"Complete\" 在我看来不是有效的 C# 代码。
猜你喜欢
  • 2021-03-12
  • 2022-07-28
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
相关资源
最近更新 更多