ballisticnylon Posted November 14, 2005 Posted November 14, 2005 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. Quote "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 PlausiblyDamp Posted November 15, 2005 Administrators Posted November 15, 2005 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Cags Posted November 15, 2005 Posted November 15, 2005 Quite a long time ago I asked a similar question. To see the suggestions I got take a look at this thread http://www.xtremedotnettalk.com/showthread.php?t=85039 Quote Anybody looking for a graduate programmer (Midlands, England)?
*Experts* Nerseus Posted November 15, 2005 *Experts* Posted November 15, 2005 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 Quote "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
ballisticnylon Posted November 15, 2005 Author Posted November 15, 2005 (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 November 16, 2005 by ballisticnylon Quote "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 PlausiblyDamp Posted November 15, 2005 Administrators Posted November 15, 2005 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
ballisticnylon Posted November 16, 2005 Author Posted November 16, 2005 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. Quote "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 PlausiblyDamp Posted November 16, 2005 Administrators Posted November 16, 2005 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.