Reflection and property enumeration

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • balabaster
    Recognized Expert Contributor
    • Mar 2007
    • 798

    Reflection and property enumeration

    okay, I'm trying to reference a property within a class using a string "class.property ", I've got a test class, imaginitively called "Test", hold your applause...it's got a property called value.

    I've got a function called GetValue that accepts an array of objects and a string for the property reference I want to get the value of.

    Now I can use reflection to create a type and use the GetProperty method to reference the "value" property:

    This gets a dynamic object of type "Test":
    Dim MyClass As Type = GetType(Test)

    at which point, I can use MyClass.GetProp erty("Value") to grab the property's value and return it...seems simple enough.

    Okay, lets add some complexity. Given that I can pass an array of objects into my function, I want to be able to give a fully qualified property name to reference:

    Lets say there's two classes, I want to specify which class to pass the value back from:
    Dim Args(1) As Object
    Args(0) = New Test1(123.45)
    Args(1) = New Test2(987.65)
    Dim Value = GetValue(Args, "Test1.Valu e")

    I think I could do this readily enough if I could pass a string value into GetType (which obviously I can't)... rather than code a switch/case to pass the correct type given a string, is there an easy way to evaluate a string as the type it refers to rather than as a string?

    (Apologies for not using code tags, the new code windows are a touch excessive for small code blocks)
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    Wait, why can't you use:
    Type.GetType(st ring name)
    ?
    Granted you would need to do a .Split('.') of some sort to get your type?

    [code=c#]
    Type tt = Type.GetType("W MI.WebDownload" );
    object o = tt.InvokeMember ("WebDownloa d", BindingFlags.Cr eateInstance, null, null, new object[] { "http://www.google.com" , @"c:\ggg.htm l" });
    tt.InvokeMember ("GetWebObject" , BindingFlags.De fault|BindingFl ags.InvokeMetho d, null, o, null);
    [/code]

    I have a namespace called "WMI" and a class called "WebDownloa d" in it. For my purpose I needed to create an instance of the class (The first InvokeMember() call, the object[] is the constructors arguments) and assigned it to object o. I then used the second InvokeMethod to invoke the method "GetWebObje ct", which has no arguments, but I told it to invoke that method on object o. Since o is of type WebDownload, it executed my code. I check with breakpoints and it really does enter into that function.

    Somewhere in all of that should be an idea to help you out? You could apply the same logic as the BindingFlags.In vokeMethod call, only change the flags to be like "return property" or whatever they are

    Comment

    • balabaster
      Recognized Expert Contributor
      • Mar 2007
      • 798

      #3
      hehe, I'd forgotten I'd posted this. So, here was my solution... for the moment. I'm going to design something recursive in the long run, but this was my prototype:

      Code:
      Function GetValue(ByVal MyInstance As IMyInterface, ByVal ValuePath As String) As Double
      
          Dim AssemblyName As String = Reflection.Assembly.GetExecutingAssembly().GetName.Name
          Dim PathNodes As List(Of String) = ValuePath.Split(".").ToList
      
          If PathNodes(0) <> AssemblyName Then PathNodes.Insert(0, AssemblyName)
      
          Dim CrntInstance As Object = MyInstance
      
          For i As Integer = 2 To PathNodes.Count - 1
      
              Dim CrntType As Type = CrntInstance.GetType()
              Dim CrntProperty As String = PathNodes(i)
              Dim dynProperty As Reflection.PropertyInfo = CrntType.GetProperty(CrntProperty)
              Dim CrntValue = dynProperty.GetValue(CrntInstance, _
                                             System.Reflection.BindingFlags.GetProperty, _
                                             Nothing, _
                                             Nothing, _
                                             Nothing)
              CrntInstance = CrntValue
      
          Next
      
          Return CrntInstance
      
      End Function
      I'm not sure I like the use of Split() to do it... but I can't think of anything more appropriate.
      Last edited by balabaster; Sep 22 '08, 05:30 PM. Reason: Why won't [code][/code] display properly?!?!

      Comment

      Working...