Check if extends or implements

Monkey Forums/Monkey Programming/Check if extends or implements

Limey(Posted 2011) [#1]
Is there a way to check if a class implements a specific interface or class?

Eg: If(ClassName(objectRef))

This works if the class does extend/implement the class/interface, but will cause an error if not.


muddy_shoes(Posted 2011) [#2]
If you mean that a compilation error is thrown if the type of "objectRef" is known at compilation and is not castable to "ClassName", then that's correct. Why would you have such a test in that situation though?

If that's not what you mean then it would help if you can provide a more complete code example for us.


Limey(Posted 2011) [#3]
What I'm looking for is the equivalent to C# 'is' keyword.



Then in my render loop.



My plan was to have a single base class that handles things like children, position, rotation and the like.

When a new base class is created it will be added as a child of another base object or to a scene list.

Each loop the scene draws all base objects in its list that implement IDrawable.

Here is where the problem lies. Not all classes that extend Base will implement IDrawable.

An example would be a pivot item that isn't drawn, but everything is parented to it.

I could get around this it's just a feature of C# that I am used to.


muddy_shoes(Posted 2011) [#4]
What is the definition of Scene and what is the error you're talking about? Is it a compilation error or a runtime error? If it's a runtime error, is it in one target or all targets?


muddy_shoes(Posted 2011) [#5]
Actually, I can see that the code you've got won't compile because Base doesn't implement IDrawable therefore the compiler knows that you can't cast your loop instance to IDrawable and tells you so. If you want to do that loop you need to have a loop instance of a type that can possibly be cast to IDrawable. Object would do.

Edit: Having said that, the behaviour does seem a bit odd. I shall go and try a few things.


marksibly(Posted 2011) [#6]
Hi,

You can only currently cast to classes known to implement an interface (eg: you can cast 'Sprite' to 'Drawable') so you'll need to work around it for now.

This is likely to be implemented later, once interfaces settle down a bit.

As a fix, you could either a 'Draw' method to base, or perhaps even maintain a queue of 'Drawables' that base objects can add themself too during update?


Limey(Posted 2011) [#7]
That works perfect. Thank you. :D


muddy_shoes(Posted 2011) [#8]
Yes, strangely Monkey seems happy enough to accept that Object can be cast to an interface, but not a defined class.

In case anyone is wondering what I'm waffling about. This works fine:

Interface A
	Method InterfaceA()
End

Class B	
End

Class C extends B implements A
	Method InterfaceA()
		Print "This is an A interface call"
	End
End

Function Main()
	Local arr:B[] = [New B(), New C(), New B(), New C()]
	
	for Local test:Object = Eachin arr
		If A(test)
			Print "test is an A"	
			A(test).InterfaceA()
		Else
			Print "test isn't an A"	
		End
	End
End



marksibly(Posted 2011) [#9]
Hi,

This works!

You just need to upcast to Object before downcasting to interface. Now that I think about it, I left it that way instead of allowing cross-casts everywhere to keep things a bit cleaner.

But note that downcasting is pretty slow - a single 'nop' method is probably much faster.

Interface Drawable
End

Class Base
End

Class Sprite Extends Base Implements Drawable
End

Function Main()

	For Local it:=Eachin [New Base,New Sprite,New Base,New Sprite]
	
		If Drawable( Object(it) )
			Print "Drawable!"
		Endif
	Next
		
End