Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Let's say that I have a function that gets passed in an object, and deals with it according to it's type. Which is the better way?

 

Private Sub DoSomething(ByVal O as Object)
    If TypeOf(O) Is apple Then
         ' do something
    ElseIf TypeOf(O) Is orange Then
         ' do something else
    End If
End Sub

 

or

 

Private Sub DoSomething(ByVal O as Object)
    Select Case O.GetType.Name
         Case "apple"
              ' do something
         Case "orange"
              ' do something else
    End Select
End Sub

 

For some reason, you can't do Select Case O.GetType.

"It may be roundly asserted that human ingenuity cannot concoct a cipher which human ingenuity cannot resolve."

 

- Edgar Allan Poe, 1841

 

I long to accomplish great and noble tasks, but it is my chief duty to accomplish humble tasks as though they were great and noble. The world is moved along, not only by the mighty shoves of its heroes, but also by the aggregate of the tiny pushes of each honest worker.

 

- Helen Keller

  • Administrators
Posted

Select Case only works with the basic data types provided by .Net hence the limitation.

As to which way is better I would probably tend to neither, although without knowing more about the objects in question it's hard to give a definitive answer.

Normally some form of polymorphism (Inheritance or Interface implementation) would be a good tool to apply here - but again without knowing exactly what kind of things you would be doing to the objects it's hard to say.

If possible could you give an example of what you would be doing - even if it is only using the example of fruit you gave abouve.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

  • *Experts*
Posted

To elaborate on PD's comment, rather than have a generic DoSomething(object) function, you might want to define an interface like IDoSomething (reading that afterwards, it sounds funny - "I do something" - nevermind).

 

IDoSomething would define a method, DoSomething. Then you would have code like (C#):

((IDoSomething)o).DoSomething();

 

Not sure of the syntax in VB.NET, mabye:

DirectCast(o As IDoSomething).DoSomething()

 

The idea is to cast your object as the interface IDoSomething and then call the method. Let each type of object handle the DoSomething method however it wants to.

 

-ner

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Posted (edited)

Basically, I have defined a nested class structure (things within things within things). Then I have a recursive sub that determines the type of object that gets passed in and calls itself for each object that the passed object contains. The following code fills _Cities with all the cities contained by the passed object, whether it's the world, a country, state, or county.

 

Private _Cities as CityCollection

Private Sub GetAllCities(ByVal O as object)
    Select Case O.GetType.Name
         Case "World"
              For each cntry as Country in directcast(O, World).Countries
                   GetAllCities(cntry)
              Next
         Case "Country"
              For each s as State in directcast(O, Country).States
                   GetAllCities(s)
              Next
         Case "State"
              For each co as County in directcast(O, State).Counties
                   GetAllCities(co)
              Next
         Case "County"
              For Each c as City in directcast(O, County).Cities
                   _Cities.add(c)
              Next
         Case "City"
                   _Cities.Add(directcast(O, City))
    End Select
End Sub

 

Select Case O.GetType.Name feels like a klooge, though.

Edited by ballisticnylon

"It may be roundly asserted that human ingenuity cannot concoct a cipher which human ingenuity cannot resolve."

 

- Edgar Allan Poe, 1841

 

I long to accomplish great and noble tasks, but it is my chief duty to accomplish humble tasks as though they were great and noble. The world is moved along, not only by the mighty shoves of its heroes, but also by the aggregate of the tiny pushes of each honest worker.

 

- Helen Keller

  • Administrators
Posted

If you have separate classes defined for each of these objects then you should define a standard interface that each of the other classes implements, and this would provide a method for returning a list of cities

 

Public Interface ICityProvider
   Function GetCities() As ArrayList 'use whatever collection type
End Interface

Public Class World
   Implements ICityProvider


   Public Function GetCities() As System.Collections.ArrayList Implements ICityProvider.GetCities
       Return New ArrayList    'really return a list of cities for a world here
   End Function
End Class

Public Class County
   Implements ICityProvider

   Public Function GetCities() As System.Collections.ArrayList Implements ICityProvider.GetCities
       Return New ArrayList    'really return a list of cities for a County
   End Function
End Class

'repeat for each of your other classes

each of the individual classes would need to provide it's own implementation for how to return a list of cities.

 

You could then use this interface in your GetAllCities method like so:

Private _Cities As CityCollection

   Private Sub GetAllCities(ByVal O As ICityProvider)
       _Cities.Add(O.GetCities)


   End Sub

 

the only thing you would need to do was make sure each of the other classes (World, State, County etc) return a valid list of cities.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

Wow. So the idea behind an interface is that any of my classes can implement it, and I won't have to detect the type at all, I just pass in the interface. I thank you for causing an a-ha moment. I gotta learn more about this stuff.

 

But I want to ask, was there something wrong or inefficient about detecting the type of a passed object? Why is what you're describing better? It would seem to me that (in your example code) every class that implements ICityProvider and has the comment "really return a list of cities for X" would be repeating a lot of code from the other classes. The whole point of having a recursive sub was to reuse that logic.

"It may be roundly asserted that human ingenuity cannot concoct a cipher which human ingenuity cannot resolve."

 

- Edgar Allan Poe, 1841

 

I long to accomplish great and noble tasks, but it is my chief duty to accomplish humble tasks as though they were great and noble. The world is moved along, not only by the mighty shoves of its heroes, but also by the aggregate of the tiny pushes of each honest worker.

 

- Helen Keller

  • Administrators
Posted

Each class could simply call the .GetCities method of the objects it contains to build the list it returns without needing to duplicate the code.

The big problem with detectingthe object type at runtie is maintaining the code, if you add a new class that also needs to return a llst of cities you would have to go back and revise your GetCities(o as object) method to include checks for the new class, plus the testing etc involved. Using an interface you add the new class without having to revise any of the existing logic.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...