在roslyn CSharpScript评估器中使用DateTime会返回错误代码'Expected;'。虽然字符串可以正常工作。
将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 => i.TargetDateTime > 10/25/2019 11:00:00 AM"
。用引号引起来将其解释为字符串。
EDIT:我应该在上面的示例中添加对字符串进行硬编码也会失败,并显示相同的错误消息,这使我相信这是一个解析问题?不确定如何处理DateTime对象中的字符?
问题就如您所说-字符串解析为无效的C#代码"i => i.TargetDateTime > 10/25/2019 11:00:00 AM"
。即使添加了引号,也无法直接比较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()})";