CallByName Help? - Part Duh...

Posted on 2011-03-22
Last Modified: 2012-05-11
Is there a way I can use CallByName to call a private property residing inside a method?

For instance...  the following code allows me to assign Namespace.Class.Method, or Namespace.Class.Property, or string

Now what I am finding is that if the property/method is not public, i get nothing in return

Private methods...fine, I can deal with that....  but there are a few instances where I need the private properties that reside inside a public method.
Private Function Invoker(ByVal MethodName As String, Optional ByVal NamespaceName As String = Nothing, Optional ByVal ClassName As String = Nothing, Optional ByVal PropertyName As String = Nothing, Optional ByVal StringValue As String = Nothing, Optional ByVal Params() As Object = Nothing) As String
            If (Len(PropertyName) > 0) Then
                If (Len(ClassName) > 0) Then
                    If Not (Len(NamespaceName) > 0) Then
                        _IT = Type.GetType(ClassName, True, True)
                        _IT = Type.GetType(NamespaceName & "." & ClassName, True, True)
                    End If
                    _IT = Type.GetType(Me.ToString, True, True)
                End If
                Return CallByName(Activator.CreateInstance(_IT), PropertyName, CallType.Get)
            ElseIf Len(StringValue) > 0 Then
                Return StringValue
                If (Len(ClassName) > 0) Then
                    If Not (Len(NamespaceName) > 0) Then
                        _IT = Type.GetType(ClassName, True, True)
                        _IT = Type.GetType(NamespaceName & "." & ClassName, True, True)
                    End If
                    _IT = Type.GetType(Me.ToString, True, True)
                End If
                If IsNothing(Params) Then
                    Return CallByName(Activator.CreateInstance(_IT), MethodName, CallType.Get)
                    Return CallByName(Activator.CreateInstance(_IT), MethodName, CallType.Method, Params)
                End If
            End If
        End Function

Open in new window

Question by:kevp75
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
LVL 96

Accepted Solution

Bob Learned earned 500 total points
ID: 35195203
I would suggest using System.Reflection classes (MethodInfo, PropertyInfo, FieldInfo, etc.).  These classes have overloaded methods, which use the BindingFlags enumeration flag to control which type of members to access.

PropertyInfo Class (System.Reflection).

Imports System
Imports System.Reflection

Module Module1

    Sub Main()
        ' This variable holds the amount of indenting that 
        ' should be used when displaying each line of information.
        Dim indent As Int32 = 0
        ' Display information about the EXE assembly.
        Dim a As [Assembly] = System.Reflection.Assembly.GetExecutingAssembly()
        Display(indent, "Assembly identity={0}", a.FullName)
        Display(indent + 1, "Codebase={0}", a.CodeBase)

        ' Display the set of assemblies our assemblies reference.
        Dim an As AssemblyName
        Display(indent, "Referenced assemblies:")
        For Each an In a.GetReferencedAssemblies()
            Display(indent + 1, "Name={0}, Version={1}, Culture={2}, PublicKey token={3}", _
                an.Name, an.Version, an.CultureInfo.Name, BitConverter.ToString(an.GetPublicKeyToken))
        Display(indent, "")

        ' Display information about each assembly loading into this AppDomain.
        For Each a In AppDomain.CurrentDomain.GetAssemblies()
            Display(indent, "Assembly: {0}", a)

            ' Display information about each module of this assembly.
            Dim m As [Module]
            For Each m In a.GetModules(True)
                Display(indent + 1, "Module: {0}", m.Name)

            ' Display information about each type exported from this assembly.
            Dim t As Type
            indent += 1
            For Each t In a.GetExportedTypes()
                Display(0, "")
                Display(indent, "Type: {0}", t)

                ' For each type, show its members & their custom attributes.
                Dim mi As MemberInfo
                indent += 1
                For Each mi In t.GetMembers()
                    Display(indent, "Member: {0}", mi.Name)
                    DisplayAttributes(indent, mi)

                    ' If the member is a method, display information about its parameters.
                    Dim pi As ParameterInfo
                    If mi.MemberType = MemberTypes.Method Then
                        For Each pi In CType(mi, MethodInfo).GetParameters()
                            Display(indent + 1, "Parameter: Type={0}, Name={1}", pi.ParameterType, pi.Name)
                    End If

                    ' If the member is a property, display information about the property's accessor methods.
                    If mi.MemberType = MemberTypes.Property Then
                        Dim am As MethodInfo
                        For Each am In CType(mi, PropertyInfo).GetAccessors()
                            Display(indent + 1, "Accessor method: {0}", am)
                    End If
                indent -= 1
            indent -= 1
    End Sub

    ' Displays the custom attributes applied to the specified member.
    Sub DisplayAttributes(ByVal indent As Int32, ByVal mi As MemberInfo)
        ' Get the set of custom attributes; if none exist, just return.
        Dim attrs() As Object = mi.GetCustomAttributes(False)
        If attrs.Length = 0 Then Return

        ' Display the custom attributes applied to this member.
        Display(indent + 1, "Attributes:")
        Dim o As Object
        For Each o In attrs
            Display(indent + 2, "{0}", o.ToString())
    End Sub

    ' Display a formatted string indented by the specified amount.
    Sub Display(ByVal indent As Int32, ByVal format As String, ByVal ParamArray params() As Object)
        Console.Write(New String(" "c, indent * 2))
        Console.WriteLine(format, params)
    End Sub
End Module

'The output shown below is abbreviated.
'Assembly identity=Reflection, Version=, Culture=neutral, PublicKeyToken=null
'  Codebase=file:///C:/Reflection.exe
'Referenced assemblies:
'  Name=mscorlib, Version=1.0.5000.0, Culture=, PublicKey token=B7-7A-5C-56-19-34-E0-89
'  Name=Microsoft.VisualBasic, Version=7.0.5000.0, Culture=, PublicKey token=B0-3F-5F-7F-11-D5-0A-3A
'Assembly: mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
'  Module: mscorlib.dll
'  Module: prc.nlp
'  Module: prcp.nlp
'  Module: ksc.nlp
'  Module: ctype.nlp
'  Module: xjis.nlp
'  Module: bopomofo.nlp
'  Module: culture.nlp
'  Module: region.nlp
'  Module: sortkey.nlp
'  Module: charinfo.nlp
'  Module: big5.nlp
'  Module: sorttbls.nlp
'  Module: l_intl.nlp
'  Module: l_except.nlp
'  Type: System.Object
'    Member: GetHashCode
'    Member: Equals
'      Parameter: Type=System.Object, Name=obj
'    Member: ToString
'    Member: Equals
'      Parameter: Type=System.Object, Name=objA
'      Parameter: Type=System.Object, Name=objB
'    Member: ReferenceEquals
'      Parameter: Type=System.Object, Name=objA
'      Parameter: Type=System.Object, Name=objB
'    Member: GetType
'    Member: .ctor
'  Type: System.ICloneable
'    Member: Clone
'  Type: System.Collections.IEnumerable
'    Member: GetEnumerator
'      Attributes:
'        System.Runtime.InteropServices.DispIdAttribute
'  Type: System.Collections.ICollection
'    Member: get_IsSynchronized
'    Member: get_SyncRoot
'    Member: get_Count
'    Member: CopyTo
'      Parameter: Type=System.Array, Name=array
'      Parameter: Type=System.Int32, Name=index
'    Member: Count
'      Accessor method: Int32 get_Count()
'    Member: SyncRoot
'      Accessor method: System.Object get_SyncRoot()
'    Member: IsSynchronized
'      Accessor method: Boolean get_IsSynchronized()

Open in new window

Type.GetMethods Method (BindingFlags)

Imports System
Imports System.Reflection
Imports System.Reflection.Emit
Imports Microsoft.VisualBasic

' Create a class having two public methods and one protected method.
Public Class MyTypeClass
    Public Sub MyMethods()
    End Sub 'MyMethods
    Public Function MyMethods1() As Integer
        Return 3
    End Function 'MyMethods1
    Protected Function MyMethods2() As [String]
        Return "hello"
    End Function 'MyMethods2
End Class 'MyTypeClass
Public Class TypeMain
    Public Shared Sub Main()

        Dim myType As Type = GetType(MyTypeClass)
        ' Get the public methods.
        Dim myArrayMethodInfo As MethodInfo() = myType.GetMethods((BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly))
        Console.WriteLine((ControlChars.Cr + "The number of public methods is " & myArrayMethodInfo.Length.ToString() & "."))
        ' Display all the public methods.
        ' Get the nonpublic methods.
        Dim myArrayMethodInfo1 As MethodInfo() = myType.GetMethods((BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.DeclaredOnly))
        Console.WriteLine((ControlChars.Cr + "The number of protected methods is " & myArrayMethodInfo1.Length.ToString() & "."))
        ' Display all the nonpublic methods.
    End Sub 'Main

    Public Shared Sub DisplayMethodInfo(ByVal myArrayMethodInfo() As MethodInfo)
        ' Display information for all methods.
        Dim i As Integer
        For i = 0 To myArrayMethodInfo.Length - 1
            Dim myMethodInfo As MethodInfo = CType(myArrayMethodInfo(i), MethodInfo)
            Console.WriteLine((ControlChars.Cr + "The name of the method is " & myMethodInfo.Name & "."))
        Next i
    End Sub 'DisplayMethodInfo
End Class 'TypeMain	

Open in new window

LVL 25

Author Comment

ID: 35197997
Doesnt callbyname inherit from Reflection?  Or is it more a simplified version?

I will have to mess around with what you posted above and make it do what I need, so it may take some time to get back to you on whether I can get it to work with how I need it to work. :)

Will that allow me to fire the properties/methods off, or is this just gathering information?
LVL 96

Expert Comment

by:Bob Learned
ID: 35198722
CallByName was included for backward compatibility with VB6, and may be a simplified wrapper for Reflection, but it appears to be too limited.  The MethodInfo class has the Invoke method to execute the method.

Featured Post

Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below.…
This video shows how to use Hyena, from SystemTools Software, to update 100 user accounts from an external text file. View in 1080p for best video quality.

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question