gpt4 book ai didi

c# - 构建表达式以使用 DateTime 调用 StringBuilder.Append(Object) 时出现异常

转载 作者:太空宇宙 更新时间:2023-11-03 22:14:49 25 4
gpt4 key购买 nike

我构建了一个 ToStringBuilder(发现 here),它反射(reflect)类型并动态构建 Expression 以编译快速 ToString 方法。

它运行良好,但我刚刚发现它在 DateTimes 上出错。当尝试构建对传递 DateTimeStringBuilder.Append(Object) 的调用时,它会阻塞。我是否需要为框值类型创建表达式?如何做到最好?

我创建了以下测试用例来演示失败。

    // passes
[Test]
public void AppendDateTime()
{
StringBuilder sb = new StringBuilder();
sb.Append(new DateTime());
}


// throws
[Test]
public void ExpressionAppendDateTime()
{
ParameterExpression sbArgExpression = Expression.Parameter(typeof(StringBuilder), "sb");
ParameterExpression dateTimeArgExpression = Expression.Parameter(typeof(DateTime), "dateTime");

var appendMethod = typeof(StringBuilder).GetMethod("Append", new[] {typeof(DateTime)});
var call = Expression.Call(sbArgExpression, appendMethod, dateTimeArgExpression);

// throws on this line
var lambda = Expression.Lambda<Action<StringBuilder, DateTime>>(call, sbArgExpression, dateTimeArgExpression).Compile();

var datetime = new DateTime();
var sb = new StringBuilder();
lambda.Invoke(sb, datetime);
}

异常(exception)是..

System.ArgumentException was unhandled by user code
Message=Expression of type 'System.DateTime' cannot be used for parameter of type 'System.Object' of method 'System.Text.StringBuilder Append(System.Object)'
Source=System.Core
StackTrace:
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments)
at Tests.TestToStringBuilder.ExpressionAppendDateTime() in
InnerException:

最佳答案

已解决,必须使用 Expression.TypeAs 将非原始值类型键入为 Object

    [Test]
public void ExpressionAppendDateTime()
{
ParameterExpression sbArgExpression = Expression.Parameter(typeof(StringBuilder), "sb");
ParameterExpression dateTimeArgExpression = Expression.Parameter(typeof(DateTime), "dateTime");

var appendMethod = typeof(StringBuilder).GetMethod("Append", new[] {typeof(DateTime)});

Type t = typeof(DateTime);
Expression arg;
if (t.IsValueType && !t.IsPrimitive)
{
arg = Expression.TypeAs(dateTimeArgExpression, typeof(object));
}
else
{
arg = dateTimeArgExpression;
}

var call = Expression.Call(sbArgExpression, appendMethod, arg);

var lambda = Expression.Lambda<Action<StringBuilder, DateTime>>(call, sbArgExpression, dateTimeArgExpression).Compile();

var datetime = new DateTime();
var sb = new StringBuilder();
lambda.Invoke(sb, datetime);
}

关于c# - 构建表达式以使用 DateTime 调用 StringBuilder.Append(Object) 时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5459189/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com