Super type and Reflection issue

BlitzMax Forums/BlitzMax Programming/Super type and Reflection issue

Armitage 1982(Posted 2011) [#1]
Hi

I'm using the Reflection class like this:

Type Obj1
	Field X:Int = 5
	Field Y:Int = 10
	
	Method printMe()
		Print "(From obj1) X:" + X + " - Y:" + Y
	End Method
	
End Type

Type Obj2
	Field XF:Float = 99.0
	Field YF:Float = 77.0
	
	Method printMe()
		Print "(From obj2) XF:" + XF + " - Y:" + YF
	End Method
	
End Type

Type primary

	Field myObj:obj1 = New Obj1
	
	Rem
	bbdoc: Cycle every object Field and print every field
	end Rem
	Method invokeObjectMethod(obj:Object, methodName:String)
		Local id:TTypeId = TTypeId.ForObject(obj)
		For Local TF:TField = EachIn id.EnumFields()
			Local TM:TMethod = TF.TypeId().FindMethod(methodName)
			Local TFO:Object = TF.get(obj)
			If TM And TFO Then TM.Invoke(TFO, Null)
		Next		
	End Method
		
End Type

Type secondary Extends primary

	Field myObj:Obj2 = New Obj2
	
End Type


Local sec:secondary
sec = New secondary

sec.invokeObjectMethod(sec, "printMe")


This code will print the following:
(From obj1) X:5 - Y:10
(From obj2) XF:99.0000000 - Y:77.0000000


The problem is the method printMe() from the super type obj1 still present in the extend.
I would like to invoke the last printMe() from the extended class obj2 only. Not both, but how can I do that in Reflection without explicitly naming something.

Using Final Abstract Super but where ??
Would be nice if not having to create an intermediate type too.
Any idea?

Last edited 2011


Azathoth(Posted 2011) [#2]
Because secondary has two fields named myObj, myObj:Obj2 in secondary is hiding myObj:Obj1 in primary.

sec.myObj ' <- secondary's myObj:Obj2
primary(sec).myObj ' <- primary's myObj:Obj1

Last edited 2011


Armitage 1982(Posted 2011) [#3]
Yes, the Field is hidden because of the same name but even if you can access the first Field by giving his "absolute path"(primary(sec).myObj) it won't help me in the invokeObjectMethod().

It's a bit dirty but I try to exclude the first myObj Field by adding another nested loop in my invokeObjectMethod().

This new loop simply check if the current myObj type exist in both super type and current type and decide to skip the super type one thanks to a flag.
It will only work for the first level of inheritance though.

But for some reason at the moment it's not working in my framework... And after all it's not the way to go. It's like if an option in reflection is missing for that special case.



I wonder if this exist in Monkey with the new OO options.


Zeke(Posted 2011) [#4]
change this:
For Local TF:TField = EachIn id.EnumFields()

to this:
For Local TF:TField = EachIn id.Fields()



Azathoth(Posted 2011) [#5]
I don't understand why you'd want to hide the field instead passing it a new object in secondary's constructor.


Armitage 1982(Posted 2011) [#6]
Thanks a lot Zeke, It's working ! :D

... I'm a little bit embarrassed as it was written this on the manual :
Only returns fields declared in this type, not in super types.


But for my defense, only have "Get list of fields" in the summary (like EnumFields) ^^

Great, I can stop messing with that thanks to ya :)