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

时间:2015-02-03 13:27:47

标签: vb.net lambda

我构建了一个VB.NET代码来排序几个类型的字符串,数字......现在我尝试过日期。

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 = {“Aucuneméthode'ToString(”yyyy MM dd“)'n'existe sur le type'System.Nullable`1 [System.DateTime]'。”}

Google翻译

  

“没有方法”ToString(“yyyy dd MM”)'存在于'System.Nullable`1 [System.DateTime]'类型上。

我尝试过Ticks,Date或Year ,, Value.Ticks,GetValueOrDefault.Year.ToString但同样的错误

也许有更好的方式

向你求助

1 个答案:

答案 0 :(得分:1)

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

    你应该导航到&#34;价值&#34;通过检测它是否为通用Expr类型

    来对象或转换为基础对象类型作为Nullable<T>表达式的一部分