使用反射和表达式 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 但同样的错误
也许有更好的办法
感谢您的帮助
.Contains("DateTime")
将匹配 Nullable<DateTime>
和 DateTime
类型,你看到的错误是因为你试图调用 obj.Value.ToString("yyyy MM dd")
你写的是' t 可空对象上的 ToString 重载(它只是调用它包含的 ToString 方法)它是包含的 DateTime
对象 上的重载
- 反射对象上有一个布尔值,它会告诉您查看的是实际类型还是通用对象(如 Nullable<>)
- 这也是您找不到
Ticks
属性 的原因,因为它只存在于子 DateTime
对象上。在您的普通代码中 Nullable<>
对象被隐式转换为它们包含的类型(自动导航到 Value 对象)
- 查看 msdn,您将参数作为 C# 中的第 4 个参数传递,而不是在字符串中设置它们,VB 可能相同
- 我认为您不能通过调用 "Value.Ticks" 使用字符串参数导航到 Value 对象,因为首先 "Ticks" 不是方法,它是 属性,其次。 Net 无法将字符串转换为
Nullable<T>
类型的 methodInfo 对象 - 因为它不存在。
您应该导航到 "Value" 对象或转换为基础对象类型作为 Expr
表达式的一部分,方法是检测它是否是通用 Nullable<T>
类型
我构建了一个 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 但同样的错误
也许有更好的办法
感谢您的帮助
.Contains("DateTime")
将匹配Nullable<DateTime>
和DateTime
类型,你看到的错误是因为你试图调用obj.Value.ToString("yyyy MM dd")
你写的是' t 可空对象上的 ToString 重载(它只是调用它包含的 ToString 方法)它是包含的DateTime
对象 上的重载
- 反射对象上有一个布尔值,它会告诉您查看的是实际类型还是通用对象(如 Nullable<>)
- 这也是您找不到
Ticks
属性 的原因,因为它只存在于子DateTime
对象上。在您的普通代码中Nullable<>
对象被隐式转换为它们包含的类型(自动导航到 Value 对象) - 查看 msdn,您将参数作为 C# 中的第 4 个参数传递,而不是在字符串中设置它们,VB 可能相同
- 我认为您不能通过调用 "Value.Ticks" 使用字符串参数导航到 Value 对象,因为首先 "Ticks" 不是方法,它是 属性,其次。 Net 无法将字符串转换为
Nullable<T>
类型的 methodInfo 对象 - 因为它不存在。
您应该导航到 "Value" 对象或转换为基础对象类型作为 Expr
表达式的一部分,方法是检测它是否是通用 Nullable<T>
类型