Я построил ToStringBuilder (найдено здесь ), который отражает типы и динамически создает Expression
s для быстрой компиляции ToString
методов.
Он работает хорошо, но яМы только что обнаружили ошибки на DateTimes
.Он задыхается при попытке построить вызов на StringBuilder.Append(Object)
, пропуская DateTime
.Нужно ли создавать выражения для типов значений бокса?Как это лучше всего сделать?
Я создал следующий тестовый пример, чтобы продемонстрировать ошибку.
// 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);
}
Исключение составляет ..
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: