views:

157

answers:

3

Hello. I have a function

Public MyObj as Object

Public Function Test(t as Type) as Boolean
 Return TypeOf MyObj is t ' does not work
End Function

Thanks.

* EDIT

====================================================================

For clarity I will use a complete example, a little modified that initially was thought.

I use an interface, and would like to know if the objects(implementing I) passed in argument are the same type as a internal field(I; A:I; AA:A; B:I).

First of all, (a) I need the exact class identification (only A=A, B=B, AA=AA) and I'd like also (b) to have a "inheritance equivalency" (A=A and A=AA but A<>B)

Option Strict On
Option Explicit On

Public Class Form1
  ' object to test
  Private objI As I

  Private Sub Button1_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button1.Click
    Dim aObj As New A
    Dim aaObj As New AA
    Dim bObj As New B

    'assing the object to test - A
    Me.objI = New A

    'test it
    MessageBox.Show(SameTypeAs(aObj).ToString()) ' need True here
    MessageBox.Show(SameTypeAs(bObj).ToString()) ' need False here
    MessageBox.Show(SameTypeAs(aaObj).ToString()) ' need a)Flase and b)True here
  End Sub

  Function SameTypeAs(ByVal iObj As I) As Boolean
    ' here is the "problem":
    ' how to detect the same (sub)types of I?
    Return Me.objI Is iObj
  End Function

  ' interface..........
  Interface I
  End Interface

  ' class A..........
  Class A
    Implements I
  End Class

  ' class B..........
  Class B
    Implements I
  End Class

  ' class AA..........
  Class AA
    Inherits A
  End Class
End Class
+1  A: 

You could simply do:

Return GetType(MyObj).Equals(t)
Tim
e... why **Return MyObj is t** shouldn't work?
serhio
@serhio: Because "is" requires a compile-time type to work.
Jon Skeet
@Jon this code compiles, however.
serhio
@serhio: Sorry, I mean that `TypeOf ... Is ...` requires a compile-time type. If you use `Return MyObj is t` that will *only* return true if MyObj is exactly `GetType(Type)` - it's comparing the *value* of `MyObj` with the *type* `t`, rather than the *type* of the value of `MyObj`.
Jon Skeet
+3  A: 

Instead of comparing types for equality, you probably want to use Type.IsAssignableFrom:

return t.IsAssignableFrom(MyObj.GetType())

If you look at the the TypeOf ... Is ... operator documentation you'll see it requires a type name as the second operand. This type name is resolved at compile-time.

EDIT: If you really want exact equality, then TypeOf ... Is ... wouldn't have worked for you anyway.

As for the difference, consider:

MyObj = New MemoryStream()

...

Dim result = Test(GetType(Stream))

Do you want result to be true or false? If you want it to be false, you should use simple equality:

return t is MyObj.GetType()

If you want it to be true because MyObj is assignment compatible with Stream, you should use the code at the top of this answer. That would be the behaviour of TypeOf MyObject Is Stream, which is why it was my initial answer.

EDIT: Okay, answering the changed question:

Function SameTypeAs(ByVal iObj As I) As Boolean
  Return Me.objI.GetType() = iObj.GetType()
End Function

Function CompatibleType(ByVal iObj As I) As Boolean
  Return Me.objI.GetType().IsAssignableFrom(iObj.GetType())
  ' Or this depending on which way round you want compatibility
  ' Return iObj.GetType().IsAssignableFrom(Me.objI.GetType())
End Function

Note that this isn't null-safe - if you pass in Nothing or if Me.objI is nothing, you'll get a NullReferenceException on the call to GetType().

Jon Skeet
what is the difference?
serhio
Editing in that case...
Jon Skeet
just an add: what if instead of **t as Type** where *obj as Object*?
serhio
@serhio: I can't see how that would help.
Jon Skeet
I added a edit to the question, to be more clear. Thanks.
serhio
A: 

Finally, for a) point I seem to find a solution:

  Function SameTypeAs(ByVal iObj As I) As Boolean
    Return CType(iObj, Object).GetType Is CType(Me.objI, Object).GetType()
  End Function

or the generic variant

  Function SameTypeAs(Of T As I)() As Boolean
    Return TypeOf Me.objI Is T
  End Function

as for the b)...

serhio
Why are you using CType here? Just calling GetType directly should be fine.
Jon Skeet
No, I think I need to use DirectCast, because is run-time optimal.Directly GetType i can't, because of interface.
serhio