NeuralJack Posted February 28, 2007 Posted February 28, 2007 (edited) I use Lists from System.Collections.Generic constantly. Love em, love em, love em. Here's my question though. I would like to broaden some functions to work on many different lists that I have. I usually avoid using variables defined initally as 'Objects' just because it seems safer to use variables defined as the type of object that you're going to use. But, for this, it looks like defining an object and assigning the proper List to it might be the only way to accomplish what I want. My guess is that using the Object variable really shouldnt be bad as long as I only use functions that the List object has. I'm trying to cut down on code, but not at the cost of stability. Let me know what you think. Dim List1 as New List(of Class1) Dim List2 as New List(of Class2) Dim List3 as New List(of Class3) Dim ListChoice as Integer = 1 Private Sub DeleteLastEntryOfChosenList() 'Select Proper List Dim SelectedList as New Object If ListChoice = 1 Then SelectedList = List1 Elseif ListChoice = 2 Then SelectedList = List2 Elseif ListChoice = 3 Then SelectedList = List3 Else SelectedList = Nothing EndIf If SelectedList IsNot Nothing Then If SelectedList.Count > 0 SelectedList.RemoveAt(SelectedList.Count - 1) EndIf EndIf End Sub Of course, my functions are much bigger than DeleteLastEntryOfChosenList and so the code consolidation would be worth it. Edit: The other thing I'll do is add a verification procedure that will check if the object SelectedList is one of the many valid types of Lists before proceeding. If i do that there really should be no harm in doing it this way, I'm guessing. Edited February 28, 2007 by NeuralJack Quote Currently Using: Visual Basic.Net 2005, .Net Framework 2.0
Administrators PlausiblyDamp Posted February 28, 2007 Administrators Posted February 28, 2007 I would avoid Object as a datatype wherever possible - in this case because the generic list class implements the IList interface anyway you could simply use 'Select Proper List Dim SelectedList As IList If ListChoice = 1 Then SelectedList = List1 ElseIf ListChoice = 2 Then SelectedList = List2 ElseIf ListChoice = 3 Then SelectedList = List3 Else SelectedList = Nothing End If If SelectedList IsNot Nothing Then If SelectedList.Count > 0 Then SelectedList.RemoveAt(SelectedList.Count - 1) End If End If and avoid the use of Object - will even compile with Option Strict On (you do use Option Strict On I'm assuming) and you still get intellisense for the SelectedList variable. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
NeuralJack Posted February 28, 2007 Author Posted February 28, 2007 Thanks PD Dim SelectedList As IList - is what I was looking for. And you caught me , my option strict is on Custom. It shall be ON from now on. Quote Currently Using: Visual Basic.Net 2005, .Net Framework 2.0
NeuralJack Posted February 28, 2007 Author Posted February 28, 2007 Hey , ya know what's fun is turning on Option Strict after you're far into a project! Actually, it's not a big deal because I was already extensively testing the object Type before I did any implicit conversions. So it looks like the main thing I need to do for Option Strict is use DirectCast and handle potential errors during the DirectCast. So there really shouldnt be much of a problem using Option Strict On. But there are one or two classes that i'm really wanting to use 'Object' variables in because the variable could hold one of many different types. If that class used a Declaration of each of those types the code would get very tedious. Is using an Object variable safe as long as you extensively check it's Type and use DirectCast when using it? Quote Currently Using: Visual Basic.Net 2005, .Net Framework 2.0
Administrators PlausiblyDamp Posted March 1, 2007 Administrators Posted March 1, 2007 (edited) If there are several different object types that you need to perform the same operation on then you should really be looking at implementing an interface. Could you give a bit more detail about the kind of objects you are using where you feel 'Object' is the best way? Edited June 5, 2007 by PlausiblyDamp Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
NeuralJack Posted March 1, 2007 Author Posted March 1, 2007 Sure , here is more detail. In the project the user can make lists of actions that they want to do. In the code the lists of commands are Generic Lists of a Command Class. In the command class there is a variable called 'action' which is an enumeration variable, because there are only so many actions you can perform. But, each action requires many different types of information to perform work. Those pieces of information are stored in different classes. So Action1 needs Class1 to store information about how to execute Action1. But Action2 needs Class2 to store information about how to execute Action2. But Some actions are able to use the same information class. Anyway, I ended up using an 'Object' variable called 'ActionObject' to hold that information class (Class1 and Class 2 in the example) in the Command Class. I then test the type of ActionObject before I ever pull information out of it to make sure it's the proper object. If i didnt use this ActionObject the only way I could see doing things is to declare an instance (or at least a declaration) of each and every information class in each and every Command class. That would take up memory, and it seems nasty, but i could be wrong. Quote Currently Using: Visual Basic.Net 2005, .Net Framework 2.0
Administrators PlausiblyDamp Posted March 1, 2007 Administrators Posted March 1, 2007 Could you not define an interface that all actions implement (IAction or similar)? That way you would never need to know the actual implementation - the majority of your code works with the interface. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
NeuralJack Posted March 1, 2007 Author Posted March 1, 2007 I have never used or defined interfaces before. So I'll read up on them and see about using them. Each time I post here I learn 100 new things. I can only guess at all the techniques i'm missing out on by not being a professional programmer and not talking to colleagues daily. I wonder if there is an IRC chat place. Quote Currently Using: Visual Basic.Net 2005, .Net Framework 2.0
MrPaul Posted March 4, 2007 Posted March 4, 2007 Different object model I interpret your description to mean that you have a class Command which represents a command/action that can be performed. Exactly what action it represents is set by an enumeration, and based on the value of this property the Command class performs the appropriate action by using another object (ActionObject) of arbitrary type which contains specific details of how to perform the action. If I've misinterpreted the situation then you can probably ignore the rest of this post. I would suggest that rather than having one Command class which deals with all actions, you have an abstract (MustInherit) generic Command class, or an ICommand interface, which specifies the methods that all commands must have. Then, create subclasses of Command (or implement ICommand) for each of the different actions that might be performed. Since each subclass will be specific to one particular action, it can store and use the relevant ActionObject object. Each subclass could also expose this object independently of the inheritance/interface, so that when correctly cast it can be accessed directly. Obviously at some point the application will need to know the specific type of Command/ICommand so that it can use the ActionObject correctly. It is unlikely that this can be completely avoided. However, using the above approach should greatly reduce the amount of type checking and casting required, and separating each action into its own Command class will aid maintainability and expandability. Good luck :cool: Quote Never trouble another for what you can do for yourself.
NeuralJack Posted March 4, 2007 Author Posted March 4, 2007 Mr. Paul you figured out my description exactly right. And thanks for introducing me to some new concepts, namely Abstract Classes /MustInherit, etc. And it's great that you can define Lists with abstract classes. So here is the basis of my new model, tell me what you guys think, I'd like to get editing old code asap. I still need to use a Cast when i pull out data.. and i'm not sure If i can avoid it. But at least I am not casting from Objects anymore in this model. What I needed here was to use a list to hold Command classes (C1, C2,...). Then I wanted to be able to pull out the data in C1, C2 from that list later. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'Make List with the Abstract Class C_Base Dim List As New List(Of C_Base) 'Create New C1 Class and Add to List Dim NewC1 As New C1 NewC1.str_C1_Specific = "From C1" List.Add(NewC1) 'Create New C2 Class and Add to the same List Dim NewC2 As New C2 NewC2.float_C2_Specific = 55.678 List.Add(NewC2) 'Get Data From Commands in the List For i As Integer = 0 To List.Count - 1 If List(i).CmdType = CommandType.Command1 Then 'Retrieve a C1 Specific Variable from list Dim GetC1 As C1 = CType(List(0), C1) Debug.WriteLine(GetC1.str_C1_Specific) ElseIf List(i).CmdType = CommandType.Command2 Then 'Retrieve a C2 Specific Variable from the same list Dim GetC2 As C2 = CType(List(1), C2) Debug.WriteLine(GetC2.float_C2_Specific) End If Next End Sub Public MustInherit Class C_Base Public ACommonVar As String Public CmdType As CommandType End Class Public Class C1 : Inherits C_Base Public Sub New() CmdType = CommandType.Command1 End Sub Public str_C1_Specific As String End Class Public Class C2 : Inherits C_Base Public Sub New() CmdType = CommandType.Command2 End Sub Public float_C2_Specific As Single End Class Public Enum CommandType Command1 Command2 End Enum Quote Currently Using: Visual Basic.Net 2005, .Net Framework 2.0
MrPaul Posted March 4, 2007 Posted March 4, 2007 Inheritance continued That looks a lot better. In this case it is clearly only to demonstrate the concept, but if your loop contained an operation to be performed on every command, then you could define that operation in C_Base and declare it MustOverride, forcing the subclasses to define their own implementation: Public MustInherit Class C_Base 'etc 'Method which is command-specific Public MustOverride Function GetData() As String End Class Public Class C1 Inherits C_Base 'etc Public Overrides Function GetData() As String Return m_str_C1_Specific End Sub End Class Public Class C2 Inherits C_Base 'etc Public Overrides Function GetData() As String Return m_float_C2_Specific.ToString() End Sub End Class This means the loop can be greatly simplified: For i As Integer = 0 To List.Count - 1 Debug.WriteLine(List(i).GetData()) Next Also note that when you do need to know the type of command, you can just test the type of the class instance, rather than requiring the enumeration: If TypeOf List(i) Is C1 Then 'Dealing with a C1 ElseIf TypeOf List(i) Is C2 Then 'Dealing with a C2 End If Good luck :cool: Quote Never trouble another for what you can do for yourself.
NeuralJack Posted March 4, 2007 Author Posted March 4, 2007 Re: Inheritance continued Yep, I plan on using a MustOverride Function 'CopyToMe'. Also, I was planning on using an enumeration variable to see what type of command it is because I actually was not going to make a class for each command type because many commands share the same type of data. For instance, some commands, only need to keep track of one string variable, while others need to keep track of many different variables. But making each command type have it's own class might be advantageous for other reasons, i'll have to think about it. It'd be best if i could work around having to pull data out as much as possible anyway, to avoid CTyping. There is a chance I could use a MustOverride function that would actually execute the Command instead of the way i'm doing it now which is me pulling out the data in an 'execution' class and then executing the command based on that data. I'll look to see if there is some reason that I cant do that. Either way, I've got lots of editing to do Thanks again. Quote Currently Using: Visual Basic.Net 2005, .Net Framework 2.0
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.