【发布时间】:2018-09-12 07:41:37
【问题描述】:
我正在尝试创建一个通用方法,该方法接受一个集合对象、对象类型的字符串表示形式和一个字典(字符串、字符串),其键包含感兴趣的属性。
然后我想根据这些输入生成一个动态 linq 查询。似乎即使在将输入集合对象转换为强类型对象之后,动态 linq 也不起作用 - 它显示 Public member 'Select' on type '{T}' not found(其中 {T} 是强类型)。
这基本上是我所拥有的:
Sub Testing123(ByVal data As Object, ByVal fieldDefs As Dictionary(Of String, String), ByVal myObjectType as String, ByVal myCollectionType As String, ByVal myAssembly As String)
' Type of object in the collection
Dim properties = Type.GetType(myObjectType).GetProperties().Where(Function(p) fieldDefs.ContainsKey(p.Name)).ToList()
' Get type of the collection object (data)
Dim thisType = Type.GetType(String.Format("{0},{1}",myCollectionType,myAssembly))
' Create strongly-typed collection object
Dim data2 = Convert.ChangeType(data, thisType)
' Resolve select list from input
Dim selectVars As String = "new (" & String.Join(", ", fieldDefs.Keys.ToList()) & ")"
' materialise dynamic query
Dim result = data2.Select(selectVars) ' ERROR IS HERE
For Each r In result
Debug.Print(r.Title & " " & r.ViewType)
Next
End Sub
如果我传入一个强类型集合对象(例如,而不是ByVal data As Object、ByVal data as MyStrongType)并执行等效的动态 linq 查询,它就可以正常工作。但似乎输入Object,即使转换成功(已在调试会话中确认),我也会收到此错误。
请注意,集合类型是自定义对象(SharePoint CSOM 对象,以防万一),而不仅仅是List(Of T)。
【问题讨论】:
-
投反对票者:感谢任何建设性的反馈...
-
Select方法只能在继承或实现IEnumerable(Of T)的类型的引用上调用。如果您的引用在编译时不知道是这种类型,那么它是不允许的。如果您知道在运行时它将是该类型,那么您可以转换为该类型,然后调用Select,尽管您还需要知道T是什么,或者声明您的方法是通用的。 -
感谢@jmcilhinney,感谢您的帮助。我已经验证了当对象是强类型时一切正常。我的代码 is 转换为支持
Select的类型(请参阅Dim data2 = Convert.ChangeType(...))。我错过了什么吗? -
Convert.ChangeType不是演员表。它返回一个Object引用。所以你试图在Object上调用Select,这是不允许的。强制转换和转换是两个不同的东西。强制转换会更改用于访问对象的引用的类型,而转换会更改对象的类型。Convert.ChangeType在您需要前者时执行后者。 -
啊,谢谢。我需要确定我是否可以动态转换 - 以前的尝试不会让我以与我在上面的
Convert.ChangeType中传递Type参数的方式相同
标签: .net vb.net linq dynamic dynamic-linq