【发布时间】:2017-04-04 21:36:14
【问题描述】:
我有一个派生自 DynamicObject 的类。我想使用属性(作为 TypeDescriptor 传递给 BindingList ApplyCoreSort)对其进行排序。我已经尝试了一些来自这里和其他站点的示例,但其中许多是 C# 并且不能很好地转换为 VB。我发现这个MSDN blog 中的方法既好又简单,但是翻译成VB 时却失败了:
Private Shared Function Sort(source As IEnumerable, [property] As String) As DynamicEntity()
Dim binder__1 = RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, [property], GetType(Example3), New CSharpArgumentInfo() {CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, Nothing)})
Dim param = Expression.Parameter(GetType(DynamicEntity), "o")
Dim getter = Expression.Dynamic(binder__1, GetType(Object), param)
Dim lambda = Expression.Lambda(Of Func(Of DynamicEntity, Object))(getter, param).Compile()
Return source.Cast(Of DynamicEntity)().OrderBy(lambda).ToArray()
End Function
主要是因为原代码依赖动态类型,VB中的对象类型无法替代:
Func(Of DynamicEntity, Object)
对
Func<DynamicObject, dynamic>
C# 等价物如下:
private IEnumerable<DynamicObject> SortAscending(IEnumerable<DynamicObject> source, PropertyDescriptor property, ListSortDirection direction)
{
CallSiteBinder binder__1 = RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, property.Name, property.PropertyType, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
ParameterExpression param = Expression.Parameter(typeof(DynamicObject), "o");
DynamicExpression getter = Expression.Dynamic(binder__1, property.PropertyType, param);
dynamic lambda = Expression.Lambda<Func<DynamicObject, dynamic>>(getter, param).Compile();
if (direction == ListSortDirection.Ascending) {
return source.Cast<DynamicObject>().OrderBy(lambda).ToList;
} else {
return source.Cast<DynamicObject>().OrderByDescending(lambda).ToList;
}
}
不幸的是,将其转换回 C# 并将其放入另一个 DLL 不起作用,因为编译器抱怨 IEnumerable 类型不支持 OrderBy 或 OrderByDescending。
任何人都可以提出一种在 VB 中使其工作的方法或提出一个实际工作的替代示例。将动态更改为对象不起作用,因为动态表达式编译器拒绝在运行时编译表达式,因为返回的是字符串而不是对象。
我检查了许多示例,但在尝试对动态对象进行排序时,它们似乎都无法正常工作,而且其中许多无法在带有 .Net Framework 4 的 VS 2010 VB 中编译。甚至是获得上述内容的方法在 VB 中工作的排序函数将不胜感激。
【问题讨论】:
标签: vb.net linq dynamic lambda vb.net-2010