Introspection

I have a superclass, let’s call it “MyClass”
I have many subclasses of this (and will have more). They all have a single constructor that is predictable.

I create a new instance of MyClass, and some of its properties will be one of its SubClasses: MyClass1, MyClass2, etc.

I can find that they are there, and what their name is (etc) using introspection.
Now I’m trying to populate the property with a new instance of that class. I can’t get the ConstructorInfo to be reported (always an empty array).

I am assuming I’d want to find the constructor and then call .invoke() on it, but with an empty array I cannot.
It kind of looks like I have to already have an instance of the class instantiated before I can do this, but that defeats my purpose (and I’m assuming isn’t the requirement).

Does someone have a VERY simple example of how to do this?

Hope this is clear enough. This is my first attempt at Introspection.

Did you create a Constructor on the Super, or rely on Xojo’s default Constructor?

And are there any parameters to the Constructor?

[quote=441748:@Chris Halford]I have a superclass, let’s call it “MyClass”
I have many subclasses of this (and will have more). They all have a single constructor that is predictable.

I create a new instance of MyClass, and some of its properties will be one of its SubClasses: MyClass1, MyClass2, etc.
[/quote]
A snippet fo code illustrating what you’re trying to do to construct one would be useful as I’m not sure I follow

@Kem Tekinay the super class has an empty constructor and one that takes a dictionary.

Your question may give me a hint of what to do next.

I assume you have something like

   Class MyClass
        Sub Constructor()
        End Sub

       Sub Constructor( d as dictionary)
       End Sub
   end class

  Class MySub
    inherits MyClass
 
         property foo as integer
  end class

or something like this

and what you want is the superclass constructor that takes a dict to set the properties in the subclass instance from the dictionary where it can ?

ie/


 dim d as new dictionary
 d.value("foo") = 123
 d.value("bar") = 999
 dim c as new MySub( d )

would result in a new instance of MySub with foo set to 123 ?

hopefully the latter

something like this should do

Sub constructor(d as dictionary)

  dim t as Introspection.TypeInfo = Introspection.GetType( self )
  dim propInfo() as Introspection.PropertyInto = t.GetProperties

  for each key as string in d.keys

   // see if we have a property with that name
    for i as integer = 0 to propInfo.ubound
      if propinfo(i).name - key then
        propinfo(i).value(self) = d.value(key)  
        exit
      end if
    next
  next

end sub

Norman,

I have a Superclass that is subclassed Dictionary. It does a lot of “smart” things to get, set, save and restore properties.
All the properties have to be integer, double, boolean, or string.
The constructors are
Constructor()
Constructor( d as mySpecialDictionary) // it’s not really called that.

if you have an object as a property of this super subclassed dictionary, it has to be the same sub-classed dictionary.
If you want an array, it has to be of the objects ( a bunch of MySpecialDictionary).

yeah, I’ll expand this in the future. But for now it’s easy to deal with: if it’s an object, it’s this. If it’s an array, it’s this.
The catch is that I want to make a pile of different sub-classes of “mySpecialDictionary”, and I don’t want mySpecialDictionary to care about knowing all of them. All it should need to know is that if there is an object, not type, that it’s some sub-class of mySpecialDictonary, and it will have a constructor that takes mySpecialDictionary as a parameter.

Within this constructor I replicate the keys and values and then call a method to copy these into the local properties. This part works fine.

What isn’t working (yet) is that I need to make a New [abc] and I can’t figure out how to do that from the Introspection classes.

OK… none of this seems easy to explain without a white board…

is it possible this isnt the right design for this problem ?
when the super needs to know a lot about the subs to just run the constructor it always makes me wonder

Norman, I don’t think so. Probably I’m not making this as clear as it would be if I posted all the code.
The super doesn’t need to know anything about the sub. The sub has one constructor that passes a dictionary to a method of the super. That’s really it.

Regardless of how many permutations I could have, I’m mandating this requirement to keep things “simple”.

I just need to now how to find out that I have a property of an object that is of type and get the constructors through introspection.

ok is the superclass something like this ?

   Class MyClass
       Inherits Dictionary
 
            Sub Constructor()
            End Sub

            Sub Constructor( d as myspecialdictionary)
            End Sub
     End Class

and then subclasses of this like

   Class MySubClass
       Inherits MyClass 
 
            Sub Constructor( d as myspecialdictionary)
            End Sub
     End Class

???
And in the subs constructor you want to invoke the supers constructor ?
this is quite literally trivial in the subs constructor that takes one param

       Super.Constructor( d )

It’s also not necessary at all since the sub will inherit the supers implementation of this constructor

or do I have this backwards and you want the super to invoke the subs constructor ?

You have it exactly right.
The super has a constructor taking a dictionary.
The sub should inherit this.
I only added the constructor to the sub-class when I was getting an empty array back for the constructor info using introspection.

quite literally the subclass doesnt need to do anything to use the supers constructor with one param
remove it from the subclass entirely

you dont need to do anything else

now maybe the superclass might read the dict & set specific properties of whatever kind of instance it got - but that is the code I posted earlier

Norman, gotcha.
Agreed.
But that’s not the problem.

I need to use introspection to determine which subclass it is and be able to instantiate a new instance of it, passing the dictionary to the constructor. I won’t know which instance of subclass it is before hand.
The subclasses will all have the same constructors, but the methods and properties will be different.

So I’ll have
Superclass A which extends Dictionary
And subclass b, c, d, e, f, which extend A

b, c, d, e, f could have properties of any type b, c, d, e, f.
When I read those I need to create a new instance passing a dictionary so that they can re-populate the properties.

More clear?

I have this working very nicely with integers, booleans, doubles, strings, and dates. The sub-class is tripping me.

Problem solved. I was doing it right all along. Simple syntax error… oops.

Your super class is calling the subclass constructor ?