Search code examples
vb.netreflectionextension-methodsdynamic-programminggeneric-programming

Why does not work the use of an extension method in the same extension method?


I got an extension method that gives me the value of every property in an instance. For scalar values works it fine. But for Collections there is a problem. This is my code:

<Extension()>
Public Function ToXml(Of T)(ByVal source As T) As XmlDocument
    Dim oXmlDocument As New XmlDocument
    oXmlDocument.AppendChild(oXmlDocument.CreateXmlDeclaration("1.0", "utf-8", Nothing))
    oXmlDocument.AppendChild(oXmlDocument.CreateElement(XmlConvert.EncodeName(source.GetType.ToString)))

    For Each Item As System.Reflection.FieldInfo In source.GetType.GetFields
        Dim oElement As XmlElement = oXmlDocument.CreateElement(XmlConvert.EncodeName(Item.MemberType.ToString))
        oElement.Attributes.Append(oXmlDocument.CreateAttribute("Name")).Value = Item.Name
        oElement.Attributes.Append(oXmlDocument.CreateAttribute("Value")).Value = Item.GetValue(source)

        oXmlDocument.DocumentElement.AppendChild(oElement)
    Next

    For Each Item As System.Reflection.PropertyInfo In source.GetType.GetProperties
        Dim oElement As XmlElement = oXmlDocument.CreateElement(XmlConvert.EncodeName(Item.MemberType.ToString))
        oElement.Attributes.Append(oXmlDocument.CreateAttribute("Name")).Value = Item.Name

        If (Not (TryCast(Item.GetValue(source, Nothing), ICollection) Is Nothing)) Then
            For Each SubItem As Object In CType(Item.GetValue(source, Nothing), ICollection)
                For Each Node As XmlNode In SubItem.ToXml().DocumentElement.SelectNodes("node()")
                    oElement.AppendChild(oElement.OwnerDocument.ImportNode(Node, True))
                Next
            Next
        Else
            oElement.Attributes.Append(oXmlDocument.CreateAttribute("Value")).Value = If(Not (Item.GetValue(source, Nothing) Is Nothing), Item.GetValue(source, Nothing).ToString, "Nothing")
        End If

        oXmlDocument.DocumentElement.AppendChild(oElement)
    Next

    Return oXmlDocument
End Function

The line

For Each Node As XmlNode In SubItem.ToXml().DocumentElement.SelectNodes("node()")

throws the error Public member 'ToXml' on type 'MyClass' not found.

But if I do

Dim instance As new MyClass
instance.ToXml()

this also works. Where is my fault in the loop?

Thanks in advance for any response.


Solution

  • In VB.NET, extension methods don't work on variables declared as Object for backward compatibility.

    Try:

    Dim instance As Object = new MyClass()
    instance.ToXml()
    

    It will fail.

    So you can't call ToXml on SubItem because SubItem is of type Object.


    You can, however, just call ToXml like a regular method:

    For Each Node As XmlNode In ToXml(SubItem).DocumentElement.SelectNodes("node()")