简体   繁体   English

C# 获取可空日期时间 ToString 格式方法,带参数设置 Expression.Call

[英]C# get nullable datetime ToString format method with params to set Expression.Call

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:我正在尝试动态构建表达式 LINQ function,当我对日期时间进行字符串比较时,我得到了带有格式参数的ToString方法:

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?我需要获取DateTime?ToString格式方法吗? . .

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?这是一个带DateTime? . . You have to handle the case where to value is null, makes no sense to call ToString() in this case.您必须处理值为 null 的情况,在这种情况下调用ToString()是没有意义的。

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?"你是说“这适用于 DateTime 但不适用于 DateTime?” or is it you saying "this is what I'm trying to do with my DateTime?"?还是您说“这就是我要对我的 DateTime 做的事情?”?

As such, I cant really tell you what to do but I can point out a couple of problems you'll encounter:因此,我不能真正告诉你该怎么做,但我可以指出你会遇到的几个问题:

  • If your member.Type is returning a type of a DateTime?如果您的member.Type返回一个DateTime? it won't ever be equal to a typeof(DateTime) because they are different types.它永远不会等于typeof(DateTime)因为它们是不同的类型。 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.此外,我不确定member.Type是如何产生值的,但如果它是通过someInstance.GetType()你应该记住在 null 可空值上调用GetType()会引发 null 引用异常。 See GetType on Nullable Boolean for a lengthy discourse on this请参阅可空 Boolean 上的 GetType 以获得关于此的冗长论述
  • a DateTime? DateTime? doesn't have a ToString(string format) overload.没有ToString(string format)重载。 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..您可能需要实现一些检查member.Type是否为可空类型,然后使用可空的.Value 来代替..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM