使用反射和表达式 lambda 动态排序日期时间

Dynamically Sort Datetime with reflection and expression lambda

我构建了一个 VB.NET 代码来对字符串、数字等多种类型进行排序...现在我尝试对 Had date 进行排序。

If (TypeClass.GetProperties().Any(Function(prop) prop.Name = sortPropertyName AndAlso prop.CanRead)) Then

    'Information sur la propriété recherchée
    Dim pinfo As PropertyInfo = TypeClass.GetProperty(sortPropertyName)
    Dim Typ = pinfo.PropertyType.Name
    Dim toStr As Expression

    Dim Expr As Expression = Expression.Property(paramExpr, pinfo)

    toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(String.Empty))), "ToString", Nothing)


    Dim orderByFunc As Func(Of MaClass, Object) = Expression.Lambda(Of Func(Of MaClass, Object))(toStr, paramExpr).Compile()
    Dim sortFunc As Func(Of IEnumerable(Of MaClass), IOrderedEnumerable(Of MaClass)) = Nothing

    If (Not CBool(Sort.Sens)) Then
        sortFunc = (Function(source) source.OrderBy(orderByFunc))
    Else
        sortFunc = (Function(source) source.OrderByDescending(orderByFunc))
    End If

    query = sortFunc(query).ToList()
End If

问题是当我排序时它不是排序日期而是像

这样的字符串

31/12/2005; 31/11/2011; 31/10/2007 ...

当我排序时最好找到

31/11/2011; 31/10/2007; 31/12/2005

那我试试这个修改

 If Typ.Contains("DateTime") Then 'Add For DateTime here
     toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(Date.MinValue))), "ToString", Nothing)
Else
    toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(String.Empty))), "ToString", Nothing)
End If

但我不知道如何替换 'ToString'

我试试

toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(Date.MinValue))), "ToString(""yyyy MM dd"")", Nothing)

但是我在跟踪错误

ex = {"Aucune méthode 'ToString("yyyy MM dd")' n'existe sur le type 'System.Nullable`1[System.DateTime]'."}

由 Google

翻译

"No method 'ToString (" yyyy dd MM ")' exists on the type 'System.Nullable`1 [System.DateTime]'.

我也尝试了刻度、日期或年份,Value.Ticks,GetValueOrDefault.Year.ToString 但同样的错误

也许有更好的办法

感谢您的帮助

  1. .Contains("DateTime") 将匹配 Nullable<DateTime>DateTime 类型,你看到的错误是因为你试图调用 obj.Value.ToString("yyyy MM dd") 你写的是' t 可空对象上的 ToString 重载(它只是调用它包含的 ToString 方法)它是包含的 DateTime 对象
  2. 上的重载
  3. 反射对象上有一个布尔值,它会告诉您查看的是实际类型还是通用对象(如 Nullable<>)
  4. 这也是您找不到 Ticks 属性 的原因,因为它只存在于子 DateTime 对象上。在您的普通代码中 Nullable<> 对象被隐式转换为它们包含的类型(自动导航到 Value 对象)
  5. 查看 msdn,您将参数作为 C# 中的第 4 个参数传递,而不是在字符串中设置它们,VB 可能相同
  6. 我认为您不能通过调用 "Value.Ticks" 使用字符串参数导航到 Value 对象,因为首先 "Ticks" 不是方法,它是 属性,其次。 Net 无法将字符串转换为 Nullable<T> 类型的 methodInfo 对象 - 因为它不存在。

您应该导航到 "Value" 对象或转换为基础对象类型作为 Expr 表达式的一部分,方法是检测它是否是通用 Nullable<T> 类型