I'm trying to build dynamically build an expression LINQ function, when I do string comparison for datetime I get ToString
method with format argument:
else if (member.Type == typeof(DateTime))
{
var toString = typeof(DateTime).GetMethod("ToString", new Type[] { typeof(string) });
member = Expression.Call(member, toString, Expression.Constant("yyyyMMdd"));
}
I need to get ToString
format method of DateTime?
.
I would recommend building an expression like;
Expression<Func<T?, string>> expr = d => d.HasValue ? d.Value.ToString("...") : null;
For example;
private static Dictionary<Type,string> Formats = ...
private Expression ToString(Expression value)
{
if (value.Type.IsGenericType && value.Type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return Expression.Condition(
Expression.Property(value, "HasValue"),
ToString(Expression.Property(value, "Value")),
Expression.Constant(null, typeof(string))
);
}
var toString = value.Type.GetMethod("ToString", new Type[] { typeof(string) });
return Expression.Call(value, toString, Expression.Constant(Formats[value.Type]));
}
Here a small example with a DateTime?
. You have to handle the case where to value is null, makes no sense to call ToString()
in this case.
public class Program
{
public static void Main(string[] args)
{
DateTime? dateTime = ...;
string result = "";
if (dateTime.HasValue)
{
ConstantExpression constant = Expression.Constant(dateTime);
MethodInfo? toString = typeof(DateTime).GetMethod("ToString", new[] { typeof(string) });
MethodCallExpression call = Expression.Call(constant, toString, Expression.Constant("yyyyMMdd"));
result = Expression.Lambda<Func<string>>(call).Compile()();
}
Console.WriteLine(result);
}
}
I'm not really sure what the relevance of the code block you pasted there is; is it you saying "this works for DateTime but not DateTime?" or is it you saying "this is what I'm trying to do with my DateTime?"?
As such, I cant really tell you what to do but I can point out a couple of problems you'll encounter:
member.Type
is returning a type of a DateTime?
it won't ever be equal to a typeof(DateTime)
because they are different types. Additionally, I'm not sure how member.Type
comes to have a value but if it's via someInstance.GetType()
you should bear in mind that calling GetType()
on a null nullable throws a null reference exception. See GetType on Nullable Boolean for a lengthy discourse on thisDateTime?
doesn't have a ToString(string format)
overload. You might need to implement something that checks if member.Type
is a nullable type and then do your work with the nullable's.Value instead..
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.