我是vb.net和linq xml的新手。我正在尝试将经常使用的查询封装到函数中,这样我就可以将它们链接起来。
From tag in myelement where ... select ...
上面,mylement可以是IEnumerable(Of XElement)或XElement,visualstudio对此没有任何问题。但是如果我定义一个函数
Function select_items(ByRef myelement As IEnumerable(Of XElement), ByVal name As String) As IEnumerable(Of XElement)
Dim tags = _
From tag In myelement.Elements(ns + "item")
Where tag.Element(ns + "cc").Attribute("S") = "ITEM" _
AndAlso tag.Element(ns + "cc").Value = name
Select tag
Return tags
End Function
如果我没有输入myelement的类型,我会出现错误
Expression of type 'Object' is not queryable. Make sure you are not missing an assembly reference and/or namespace import for the LINQ provider.
如果我在函数声明中放入"myelement-As-Xelement",然后在参数中使用IEnumerable(Xelement)调用函数,它会显示错误
Unable to cast object of type 'WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.Xml.Linq.XElement]' to type 'System.Xml.Linq.XElement'.
如果我把"mylement作为(Xelement的)IEnumerable"并用Xelement调用它,我会得到相同的错误反转
所以问题是:我应该如何声明我的函数具有与from/in/where/select语句相同的多态性?
感谢
您可以在XElement
和IEnumerable(Of XElement)
上调用Elements
,但两者调用的方法不同!
第一个是真正的XContainer.Elements(name as XName)
方法调用(您可以使用String
参数来调用它,因为提供了Implicit(String to XName)
转换)。第二种是在IEnumerable(Of T As XContainer)
上设置的扩展方法。
为了使您的方法同时适用于XElement
和IEnumerable(Of XElement)
(或更通用的XContainer
和IEnumerable(Of XContainer)
),您还必须提供两种方法:
Function select_iems(ByRef myelement As XContainer, ByVal name As String) As IEnumerable(Of XContainer)
Return select_items(New List(Of XContainer)(1) From {myelement}, name)
End Function
Function select_items(ByRef myelement As IEnumerable(Of XContainer), ByVal name As String) As IEnumerable(Of XContainer)
Dim tags = _
From tag In myelement.Elements(ns + "item")
Where tag.Element(ns + "cc").Attribute("S") = "ITEM" _
AndAlso tag.Element(ns + "cc").Value = name
Select tag
Return tags
End Function