Primitive/Object casting/type-checking

Monkey Forums/Monkey Programming/Primitive/Object casting/type-checking

Samah(Posted 2013) [#1]
So basically, I want to be able to do a type check on a generic. This means it won't compile for primitives.
Class Foo<T>
  Method Bar(value:T)
    If AnotherClass(value) Then
      ' do something if value is an instance of AnotherClass
    Else
      ' do something else
    End
  End
End

I would like it to fall into the "else" block if T is a primitive. Other than doing some extern magic (urgh) I can't think of any easy way to do this. Autoboxing isn't an option.

Anyone have any ideas?
Mark, is this something you could add?

Samah


Nobuyuki(Posted 2013) [#2]
always thought breaking type agnosticism was a dirty use of generics; so if being dirty -- why not do something that's clearly illegal but only recognizably so at runtime (like some sort of voodoo cast), catching it inside a try block or testing for Null? Upcasting a prim with autoboxing disabled should result in either a Null object or some sort of catchable exception, I'm presuming.

(Edit: might want to upcast to something that is either a base of all objects that would presumably be passed as a value, or do some finagling with interfaces. )

(Edit2: Actually scratch that. Why not just overload Bar with all of the type primitives, and then one more of IAcceptableObject?)


Samah(Posted 2013) [#3]
It's for a generic sorting method, so T could be any object or primitive. I want to check if T implements the IComparable interface. If it does, use the CompareTo method. If not, call the a superclass method.

I managed to make a bit of a dirty hack with a generic utility class, and it seems to work.
Class CastUtil<T>
Private
  Global NIL:T
	
Public
  Function Cast:T(value:Int)
    Return NIL
  End

  Function Cast:T(value:Float)
    Return NIL
  End

  Function Cast:T(value:String)
    Return NIL
  End

  Function Cast:T(value:Bool)
    Return NIL
  End

  Function Cast:T(value:Object)
    Return T(value)
  End
End

So instead of AnotherClass(value), I can go CastUtil<AnotherClass>.Cast(value) and it will simply return whatever the default type is for <T> if the source value was a primitive.


Samah(Posted 2013) [#4]
(Edit2: Actually scratch that. Why not just overload Bar with all of the type primitives, and then one more of IAcceptableObject?)

Because then the developer would be required to override all of those overloads in any subclasses.


AdamRedwoods(Posted 2013) [#5]
....same thing....
Class PrimitiveString<T>
	
	Field value:T

	Method ToString:String()
		Return Cast(value)
	End
	
	Method Cast:String(i:Int)
		Return "int"
	End
	Method Cast:String(i:Float)
		Return "float"
	End
	Method Cast:String(i:Object)
		Return "object"
	End
	Method Cast:String(i:String)
		Return "string"
	End
End

Class Foo<T>
  Field t_test:PrimitiveString<T> = New PrimitiveString<T>
 
  Method Bar(value:T)
  	
  	Local t_test.value = value
  	Print t_test
 
  End

End


Could also do ToInt() instead of ToString().


Samah(Posted 2013) [#6]
What you've done there is essentially made your own box, which is not what I want.


Gerry Quinn(Posted 2013) [#7]
I did a generic sorting method, but I took a different approach. My purpose was to make sorting really simple when you just needed to do it now with arbitrary objects or primitives. Anyway it's in this thread: http://www.monkeycoder.co.nz/Community/posts.php?topic=5602 .

The reason I mention it is that, while very simplistic, it does actually avoid the problem here, because the user has to say how he wants things sorted:



Of course it doesn't work for strings, every object needs to have a float value associated with it. Still, it depends what you're trying to present to the users of your code. I just thought I'd throw it out there as an example of generic sorting...


Nobuyuki(Posted 2013) [#8]
> (Edit2: Actually scratch that. Why not just overload Bar with all of the type primitives, and then one more of IAcceptableObject?)

Because then the developer would be required to override all of those overloads in any subclasses.


I think I see where you're going with that. I'm guessing you'd rather it look "simple"/magic to the person passing in a value of a generic type to your sorter as long as the type is IComparable than say, forcing them to pass something like a Comparator<T> along with the thing to be sorted.

This is making me wish that generic interfaces were completed already; I want to revisit sorters.....