dcsimg
Login | Register   
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Tip of the Day
Language: VB7
Expertise: Intermediate
Nov 4, 2002

WEBINAR:

On-Demand

Application Security Testing: An Integral Part of DevOps


A command-line Object Browser that uses Reflection

' This code is taken from Francesco Balena's
' "Programming Microsoft Visual Basic .NET" - MS Press 2002, ISBN 0735613753
' You can read a free chapter of the book at 
' http://www.vb2themax.com/HtmlDoc.asp?Table=Books&ID=101000

Imports System.Reflection

Module MainModule

    Sub Main()
        ' Get command-line arguments.
        Dim args() As String = Environment.GetCommandLineArgs()
        Dim cmd As String = Environment.CommandLine
        Dim ty As Type
        Dim mbrTypes As MemberTypes = MemberTypes.All
        Dim mbrName As String = ""
        Dim mi As MemberInfo

        ' If no arguments, /? or /help
        If args.Length <= 1 OrElse args(1) = "/?" OrElse String.Compare(args(1), _
            "/help", True) = 0 Then
            ' Show command-line syntax and exit.
            Console.WriteLine("Command-line Type Browser - by Francesco Balena")
            Console.WriteLine("   Syntax:  typebrow typename [membername[*]]")
            Exit Sub
        End If

        Dim i As Integer = args(1).IndexOf(","c)
        If i < 0 Then
            ' Create the type as specified by first argument.
            ty = Type.GetType(args(1), False, True)
        Else
            ' Create the assembly specified in the last part of the first 
            ' argument
            Dim asmname As String = args(1).Substring(i + 1)
            Dim asm As [Assembly] = [Assembly].LoadWithPartialName(asmname)
            ' Get the type in the specified assembly.
            ty = asm.GetType(args(1).Substring(0, i), False, True)
        End If

        If ty Is Nothing Then
            ' Exit if error.
            Console.WriteLine("Unable to create type ""{0}""", args(1))
            Exit Sub
        End If

        ' If the user asked for a particular name.
        If args.Length > 2 Then
            ' Retrieve the name
            mbrName = args(2)
        End If

        ' Get the list of member info to be displayed
        Dim minfos() As MemberInfo = ty.FindMembers(mbrTypes, _
            BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.Static, _
            AddressOf CustomMemberFilter, mbrName)

        ' Display information on all these members.
        For Each mi In minfos
            Console.WriteLine(MemberDescription(mi))
        Next
    End Sub

    ' This is the custom filter for members.
    ' On entry filterCriteria holds the name of the member we're looking for.
    ' (Supports partial names with a trailing asterisk, as in "Repl*".)
    Function CustomMemberFilter(ByVal m As MemberInfo, _
        ByVal filterCriteria As Object) As Boolean
        ' Discard accessor methods for properties.
        If m.Name.StartsWith("get_") Or m.Name.StartsWith("set_") Then
            Return False
        End If

        ' Get the search filter in uppercase.
        Dim search As String = filterCriteria.ToString.ToUpper
        If search = "" Then Return True

        If search.EndsWith("*") Then
            ' If there is a trailing asterisk, checks for partial match.
            If m.Name.ToUpper.StartsWith(search.Substring(0, _
                search.Length - 1)) Then Return True
        Else
            ' Otherwise search for exact match.
            If m.Name.ToUpper = search Then Return True
        End If
    End Function

    ' Return the syntax for a member (field, property, methods, event).
    Function MemberDescription(ByVal mi As MemberInfo) As String
        Dim res As String

        ' Different treatment for different types
        Select Case mi.MemberType
            Case MemberTypes.Field
                ' Fields: append As clause.
                Dim fdi As FieldInfo = CType(mi, FieldInfo)
                res &= NameDescription(mi, fdi.IsStatic) & VBTypeDescription _
                    (fdi.FieldType)

            Case MemberTypes.Property
                ' Properties: append parameter list and return type.
                Dim pri As PropertyInfo = CType(mi, PropertyInfo)
                res &= NameDescription(mi, False) & ParamListDescription _
                    (pri.GetIndexParameters)
                res &= VBTypeDescription(pri.PropertyType)

            Case MemberTypes.Method
                ' Methods: append parameter list and return type.
                Dim mti As MethodInfo = CType(mi, MethodInfo)
                res &= NameDescription(mi, mti.IsStatic) & ParamListDescription _
                    (mti.GetParameters)
                If Not (mti.ReturnType Is Nothing) Then
                    res &= VBTypeDescription(mti.ReturnType, True)
                End If

            Case MemberTypes.Constructor
                ' Constructor
                Dim cti As ConstructorInfo = CType(mi, ConstructorInfo)
                res &= NameDescription(mi, False) & ParamListDescription _
                    (cti.GetParameters)

            Case MemberTypes.Event
                ' Events: append parameter list.
                Dim evi As EventInfo = CType(mi, EventInfo)
                ' Get the type that corresponds to the underlying delegate.
                Dim delType As Type = evi.EventHandlerType
                Dim mi2 As MethodInfo = delType.GetMethod("Invoke")
                res &= NameDescription(mi, False) & ParamListDescription _
                    (mi2.GetParameters)
        End Select

        Return res
    End Function

    ' Return a description for name.
    ' (Including Shared and member type description.)
    Function NameDescription(ByVal mi As MemberInfo, ByVal IsStatic As Boolean) _
        As String
        Dim res As String

        ' Prefix with Shared if necessary
        If IsStatic Then
            res = "Shared "
        End If

        ' Append member type, but distinguish between Sub and Function
        If mi.MemberType <> MemberTypes.Method Then
            ' if not a method, we can simply use the Enum.Format method.
            res &= [Enum].Format(mi.MemberType.GetType, mi.MemberType, _
                "G") & " "
        Else
            Dim meth As MethodInfo = CType(mi, MethodInfo)
            If meth.ReturnType.Name = "Void" Then
                res &= "Sub "
            Else
                res &= "Function "
            End If
        End If


        ' Append name and return to caller.
        If mi.MemberType = MemberTypes.Constructor Then
            ' Visual Basic constructors are named "new"
            res &= "New"
        Else
            ' A non-constructor element.
            res &= mi.Name
        End If

        Return res
    End Function

    ' Return the description for a list of parameters.
    Function ParamListDescription(ByVal pinfos() As ParameterInfo) As String
        Dim res As String = "("
        Dim i As Integer

        ' Iterate over all parameters.
        For i = 0 To pinfos.GetUpperBound(0)
            ' Append description for this parameter.
            res &= ParamDescription(pinfos(i))
            ' Append a comma if this isn't the last argument.
            If i < pinfos.GetUpperBound(0) Then res &= ", "
        Next
        ' Close the parenthesis and return to caller.
        Return res & ")"
    End Function

    ' Return a description for a single parameter.
    Function ParamDescription(ByVal pi As ParameterInfo) As String
        Dim res As String
        Dim pt As Type = pi.ParameterType

        ' Start with Optional if necessary.
        If pi.IsOptional Then res = "Optional "

        ' Append ByVal or ByRef.
        If pt.IsByRef Then
            res &= "ByRef "
        Else
            res &= "ByVal "
        End If

        ' Append the parameter name.
        res &= pi.Name
        ' Append the type, but convert it to VB syntax.
        res &= VBTypeDescription(pt)

        ' Append the default value, if there is one.
        If pi.IsOptional Then
            ' Enclose the default value within quotes if it is a string.
            If pt Is GetType(System.String) Then
                res &= " = """ & pi.DefaultValue.ToString & """"
            Else
                res &= " = " & pi.DefaultValue.ToString
            End If
        End If

        ' Return to the caller.
        Return res
    End Function

    ' Return a parameter type in VB-friendly format.
    Function VBTypeDescription(ByVal ty As Type, _
        Optional ByVal PostfixArrayMarks As Boolean = False) As String
        Dim res As String

        ' Get the return type as a string.
        res &= ty.Name
        ' Drop trailing "[]" pair, is there is one.
        If res.EndsWith("[]") Then
            res = res.Substring(0, res.Length - 2)
        End If
        ' Drop trailing *, if there is one.
        If res.EndsWith("*") Then
            res = res.Substring(0, res.Length - 1)
        End If

        ' Adjust for VB-friendly names.
        Select Case res
            Case "Int16"
                res = "Short"
            Case "Int32"
                res = "Integer"
            Case "Int64"
                res = "Long"
            Case "Void"
                ' this is the type "returned" by Sub
                Return ""
        End Select

        ' Append "AS" and "()" if this is an array.
        If Not ty.IsArray Then
            res = " As " & res
        ElseIf PostfixArrayMarks Then
            ' Append trailing () pair.
            res = " As " & res & "()"
        Else
            ' Prefix leading () pair.
            res = "() As " & res
        End If

        ' Return to the caller.
        Return res
    End Function

End Module
Francesco Balena
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date