Lists of objects without losing class Intelli-sense
-
Hi Guys, Is it possible to have a list/collection of objects that inherit from a single base object without losing Intelli-sense? Here is an example of what I mean...
Public Class baseblob
Private \_position As PointF Property position Get Return \_position End Get Set(value) \_position = value End Set End Property Sub New() position = PointF.Empty End Sub
End Class
Public Class blob
Inherits baseblob Sub moveRight(ByVal Distance As Single) position = New PointF(position.X + Distance, position.y) End Sub
End Class
Public Class Form1
Dim blob As New blob Dim blobs As New List(Of baseblob) Private Sub Button1\_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click blob.moveRight(10) MsgBox(blob.position.x) blobs.Add(blob) MsgBox(blobs(0).position.x) blobs(0).moveright(10) MsgBox(blobs(0).position.x) End Sub
End Class
... but of course in the above example i get
'moveright' is not a member of 'oopTest.baseblob'
:doh: So it wants me to use
Dim blobs As New List(Of Object)
So it will compile and work as intended... I just wanted to know is there something I'm missing here? Why can't I just let it know that it's a base object and to list all the possible methods/properties etc of the base class and also any objects that inherit the base class? Give me the lot! To me it doesn't sound like such a hard thing to ask of the compiler/dev environment... why cant it do it ? :(
-
Hi Guys, Is it possible to have a list/collection of objects that inherit from a single base object without losing Intelli-sense? Here is an example of what I mean...
Public Class baseblob
Private \_position As PointF Property position Get Return \_position End Get Set(value) \_position = value End Set End Property Sub New() position = PointF.Empty End Sub
End Class
Public Class blob
Inherits baseblob Sub moveRight(ByVal Distance As Single) position = New PointF(position.X + Distance, position.y) End Sub
End Class
Public Class Form1
Dim blob As New blob Dim blobs As New List(Of baseblob) Private Sub Button1\_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click blob.moveRight(10) MsgBox(blob.position.x) blobs.Add(blob) MsgBox(blobs(0).position.x) blobs(0).moveright(10) MsgBox(blobs(0).position.x) End Sub
End Class
... but of course in the above example i get
'moveright' is not a member of 'oopTest.baseblob'
:doh: So it wants me to use
Dim blobs As New List(Of Object)
So it will compile and work as intended... I just wanted to know is there something I'm missing here? Why can't I just let it know that it's a base object and to list all the possible methods/properties etc of the base class and also any objects that inherit the base class? Give me the lot! To me it doesn't sound like such a hard thing to ask of the compiler/dev environment... why cant it do it ? :(
The method shows up. In VB.NET, the default access modifier for a class method is Public. In C# it's private. You'd be better served by not depending on the defaults but explicitly declaring your access levels. Also, your naming convention isn't exactly clean and understandable either. In your example, how do to tell the difference between a variable called
blob
and your class calledblob
?? It should look more like:Public Class BaseBlob
Private \_position As PointF **Public** Property **Position** Get Return \_position End Get Set(value) \_position = value End Set End Property Sub New() **Position** = PointF.Empty End Sub
End Class
Public Class Blob
Inherits BaseBlob**Public** Sub **MoveRight**(ByVal **distance** As Single) **Position** = New PointF(Position.X + **distance**, Position.y) End Sub
End Class
Public Class Form1
**Private** blob As New Blob **Private** blobs As New List(Of BaseBlob) Private Sub Button1\_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click blob.MoveRight(10) MsgBox(blob.Position.x) blobs.Add(blob) MsgBox(blobs(0).Position.x) blobs(0).MoveRight(10) MsgBox(blobs(0).Position.x) End Sub
End Class
You can't tell Intellisense to show all members from every class inheriting from a base class. It's not showing you the members of Blob because you told it the collection was a collection of BaseBlob, not Blob. Do you see a member on BaseBlob called
MoveRight
?? Nope. So it's not going to show any members that inherit from classes that inherit from BaseBlob because none of them are valid! MoveRight is not applicable to a collection member of blobs because you're are treating the objects in the collection as if they were BaseBlob object. It's telling you that if you try to use one of those members, the compile will fail!A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
The method shows up. In VB.NET, the default access modifier for a class method is Public. In C# it's private. You'd be better served by not depending on the defaults but explicitly declaring your access levels. Also, your naming convention isn't exactly clean and understandable either. In your example, how do to tell the difference between a variable called
blob
and your class calledblob
?? It should look more like:Public Class BaseBlob
Private \_position As PointF **Public** Property **Position** Get Return \_position End Get Set(value) \_position = value End Set End Property Sub New() **Position** = PointF.Empty End Sub
End Class
Public Class Blob
Inherits BaseBlob**Public** Sub **MoveRight**(ByVal **distance** As Single) **Position** = New PointF(Position.X + **distance**, Position.y) End Sub
End Class
Public Class Form1
**Private** blob As New Blob **Private** blobs As New List(Of BaseBlob) Private Sub Button1\_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click blob.MoveRight(10) MsgBox(blob.Position.x) blobs.Add(blob) MsgBox(blobs(0).Position.x) blobs(0).MoveRight(10) MsgBox(blobs(0).Position.x) End Sub
End Class
You can't tell Intellisense to show all members from every class inheriting from a base class. It's not showing you the members of Blob because you told it the collection was a collection of BaseBlob, not Blob. Do you see a member on BaseBlob called
MoveRight
?? Nope. So it's not going to show any members that inherit from classes that inherit from BaseBlob because none of them are valid! MoveRight is not applicable to a collection member of blobs because you're are treating the objects in the collection as if they were BaseBlob object. It's telling you that if you try to use one of those members, the compile will fail!A guide to posting questions on CodeProject[^]
Dave KreskowiakThanks for the naming scheme advice. What I use for my project is a lot easier. It was just a quick example. I should have made it easier to read, sorry. My primary issue is that I need to have multiple class objects that behave differently (playership, enemy drone, missile etc) held in a single container so that my main loop can enumerate through them all. For example.
For i as integer = 0 to blobs.count - 1
blobs(i).AiTick
blobs(i).Move
blobs(i).Draw
Next iThe only way I could find to do this was to create a base class with the ai/move/draw methods in it and have different classes inherit from the base class and over-ride the base class's methods. The main issue i have is that these classes that inherit from the base class occasionally have extra methods. I would like to see those when i'm coding things like blobs(0).ExtraMethod like i can for the base class. I guess what i'm asking isn't possible. If ClassA inherits BaseClass and ClassB inherits BaseClass but ClassA also has an extra method called "ExtraMethod" then I already run the risk of accidently executing ExtraMethod on the item in the collection that is ClassB and causing an exception. I deal with that issue already in my code, so i don't understand why the dev environment is perfectly fine with me making a list(of Objects) and running List(0).ExtraMethod ... however when I ask it to have a list of BaseClass it doesnt goto the effort of listing what's availiable in any classes that inherit from BaseClass. I guess I will just continue to have a list(of Object) instead of a list(of BaseClass) and continue running extra methods from classes that inherit from BaseClass as I currently do by first checking the object type.
-
Thanks for the naming scheme advice. What I use for my project is a lot easier. It was just a quick example. I should have made it easier to read, sorry. My primary issue is that I need to have multiple class objects that behave differently (playership, enemy drone, missile etc) held in a single container so that my main loop can enumerate through them all. For example.
For i as integer = 0 to blobs.count - 1
blobs(i).AiTick
blobs(i).Move
blobs(i).Draw
Next iThe only way I could find to do this was to create a base class with the ai/move/draw methods in it and have different classes inherit from the base class and over-ride the base class's methods. The main issue i have is that these classes that inherit from the base class occasionally have extra methods. I would like to see those when i'm coding things like blobs(0).ExtraMethod like i can for the base class. I guess what i'm asking isn't possible. If ClassA inherits BaseClass and ClassB inherits BaseClass but ClassA also has an extra method called "ExtraMethod" then I already run the risk of accidently executing ExtraMethod on the item in the collection that is ClassB and causing an exception. I deal with that issue already in my code, so i don't understand why the dev environment is perfectly fine with me making a list(of Objects) and running List(0).ExtraMethod ... however when I ask it to have a list of BaseClass it doesnt goto the effort of listing what's availiable in any classes that inherit from BaseClass. I guess I will just continue to have a list(of Object) instead of a list(of BaseClass) and continue running extra methods from classes that inherit from BaseClass as I currently do by first checking the object type.
Purge1t wrote:
I guess what i'm asking isn't possible.
It's not possible because you're trying to violate Object Oriented Programming principles. You're putting the Move method in one object, when it actually applies to all of the objects. You have to Move the Player, Move the Missle, Move the EnemyDrone, ... Don't use a rather specific MoveRight method. It should be Move and take some kind of value(s) to tell it where to or how far to move. That should go in the Base object that these other objects inherit from. The same is true for the Draw method. Every object should draw itself, so you pass in a Graphics object that it uses to draw itself on. This is common for every object you mentioned, so it should go in the Base object they are inheriting from, not the specific objects. By the way, in your case, if you try to execute a method on an object that doesn't implement it, you don't get an exception. You get a compile-time error as the code will not compile.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
Purge1t wrote:
I guess what i'm asking isn't possible.
It's not possible because you're trying to violate Object Oriented Programming principles. You're putting the Move method in one object, when it actually applies to all of the objects. You have to Move the Player, Move the Missle, Move the EnemyDrone, ... Don't use a rather specific MoveRight method. It should be Move and take some kind of value(s) to tell it where to or how far to move. That should go in the Base object that these other objects inherit from. The same is true for the Draw method. Every object should draw itself, so you pass in a Graphics object that it uses to draw itself on. This is common for every object you mentioned, so it should go in the Base object they are inheriting from, not the specific objects. By the way, in your case, if you try to execute a method on an object that doesn't implement it, you don't get an exception. You get a compile-time error as the code will not compile.
A guide to posting questions on CodeProject[^]
Dave KreskowiakThanks Dave.
Quote:
The same is true for the Draw method. Every object should draw itself, so you pass in a Graphics object that it uses to draw itself on. This is common for every object you mentioned, so it should go in the Base object they are inheriting from, not the specific objects.
The PlayerShip class draws a circle, the Missile class draws a triangle and the EnemyDrone class draws a square. How would i know how to depict each different class type if the drawing was done in the base class? Instead of having a MustOverRide .Draw method in the base class that each of the child-classes over-ride ?
-
Thanks Dave.
Quote:
The same is true for the Draw method. Every object should draw itself, so you pass in a Graphics object that it uses to draw itself on. This is common for every object you mentioned, so it should go in the Base object they are inheriting from, not the specific objects.
The PlayerShip class draws a circle, the Missile class draws a triangle and the EnemyDrone class draws a square. How would i know how to depict each different class type if the drawing was done in the base class? Instead of having a MustOverRide .Draw method in the base class that each of the child-classes over-ride ?
You either have to have that "must override" method or you have to have an interface that every object implements that says justabout the same thing. You MUST implement something that tells the compiler that "this method is expected in this class" so that you can call it no matter what the class really is. The drawing is NOT done in the base class. It just provides a "must override" method so that each class can implement it's own drawing code, but since each drawing method implements the exact same method signature, outside code can call it without knowing exactly which type of class it is.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak