shared properties in subclasses

Hi everyone,

I am trying to write something like a key value coding mechanism for objects, where I can call computed properties by name strings. So instead of calling a property “act” of an object “foo”

result = foo.act

I would would be able to call a general getter method with the name of the method as parameter dynamically (instead of “act” as a literal I would use a string variable instead):

result = foo.getValue(“act”)

With the Introspection system as far as I know I can’t call the properties by name but by position in the property array:

myProperties = Introspection.GetType(self).GetProperties
result = myProperties(idx).Value(self)

Since I wouldn’t like to cycle through all Properties and check for the right name I setup a dictionary once at application start for every class which resolves the names of my properties to the position in the Introspection system. I stored this dictionary in the class as a shared property so it is accessable by all instants.

So far so good. Now I want this functionality for different objects by subclassing. Those subclasses should be able to use the “getValue” method by inheritance. The problem is that my dictionary which looks up the positions of the properties in the individual subclasses is shared over all the subclasses since it is a shared property of the base class.

So is there any way to store shared values in a subclass without overriding the shared property of the base class?
If not, another approach would be to have templates of the subclasses which have already implemented the overridden property.

Thanks for any suggestions,
Juergen

You could try something like this to add the feature to all objects

[code]Module AccessByNameString //*very lightly tested

Private Property classesDict As Dictionary

Function getValue(extends obj As Object, propertyName As String) As Variant

if classesDict is nil then classesDict = new Dictionary

dim ti As Introspection.TypeInfo = Introspection.GetType(obj)

dim propDict As Dictionary = classesDict.Lookup(ti, nil)

if propDict is nil then //class not loaded, create propDict and add
  propDict = new Dictionary
  dim props() As Introspection.PropertyInfo = ti.GetProperties
  for i As integer = 0 to props.Ubound
    propDict.Value(props(i).Name) = props(i)
  next
  classesDict.Value(ti) = propDict
end

dim prop As Introspection.PropertyInfo = propDict.Lookup(propertyName, nil)

if prop is nil then
  return nil
else
  return prop.Value(obj)
end

End Function

End Module[/code]

Or just fold it into your super classes.

You can also use Operator_Subscript on classes to have it read like…

result = foo("act")

Oh, to fold it into your class: make classesDict Shared but getValue as a regular instance method. Then remove obj from the parameters and change the other occurrences to self.

Basically it’s what you’re doing except the shared dictionary first keys by typeinfo into dictionaries of the propertyinfos, then by name to the individual propertyinfo (no need for an index).

http://documentation.xojo.com/index.php/Operator_Lookup

This won’t probably help, since he wants to hand over the property name as String.

probably not - now that I’ve reread the post

all those variants … ick

Yes, a dictionary in a dictionary in the superclass would do the trick, thanks a lot! Thanks as well for the tip of the Operator_Subscript.

Juergen