Arokh Posted June 21, 2007 Posted June 21, 2007 I thought I understood how this works, but I guess I was wrong: Up until now I thought using the New Keyword was to create a new Instance of for example a class, allocating space for its variables. Without specifing New it only would declare it to something and if one were to assign it to another instance of the class, only a referece would be passed. For example: Class ClassA Public VarA as String Public VarB as String End Class Dim SomeClass as New ClassA SomeClass.VarA = "A" SomeClass.VarB = "B" Dim SomeOtherClass as New ClassA SomeOtherClass = SomeClass SomeOtherClass.VarA = "B" Debug.Print(SomeClass.VarA) Now I had assumed that Debug.Print would display "A" (see explanation above), but it shows "B". So SomeOtherClass is a reference to SomeClass? How can I tell VB to make a copy of the class instead of just passing a reference? SomeOtherClass = New SomeClass doesn't work. What also interests me: Is there a difference if I omit the New Keyword in the declaration of SomeOtherClass, since I both cases only a reference is passed. Although this is offtopic, I don't wanted to create another Thread for it: The ArrayList Class for example Dim AL as New ArrayList AL(0) = "Bla" Is the same as AL.Item(0) = "Bla" How can I create my own class which also accepts parameters directly after the Class Instance Variable? Quote
Administrators PlausiblyDamp Posted June 21, 2007 Administrators Posted June 21, 2007 I've commented your code a bit in an attempt to explain... Class ClassA Public VarA as String Public VarB as String End Class ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'Creates a new instance of ClassA and assigns it to the SomeClass variable Dim SomeClass as New ClassA SomeClass.VarA = "A" SomeClass.VarB = "B" 'Creates a new instance of ClassA and assigns it to the SomeOtherClass variable Dim SomeOtherClass as New ClassA 'Assigns the SomeClass variable to the SomeOtherClass variable '- now both variables point to the original ClassA instance 'and neither points to the second instance which is now eligible for garbage collection SomeOtherClass = SomeClass 'As both variables point to the original class instance this effectively set's VarA for both SomeOtherClass.VarA = "B" Debug.Print(SomeClass.VarA) Then end result would be the same if you omitted the New keyword on the line Dim SomeOtherClass as New ClassA however the code with creates a new (but never used instance) while without you just declare a variable that can point to a valid instance. For the last question they are called Default Properties un der VB. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Arokh Posted June 21, 2007 Author Posted June 21, 2007 Then how can I copy a class instance and store it into another variable of the same type? Manually copying the variables from one to another is not really how I want to do it. he he I guess one way would be the create a 'new' function which accepts its own class and then there assign values to each variable inside the class: Class ClassA Public VarA As String Public VarB As String Public Sub New(ByVal Item As ClassA) VarA = Item.VarA VarB = Item.VarB End Sub End Class Dim SomeOtherClass as New ClassA(SomeClass) But I'm hoping there is an easier way which requires less code. Quote
Leaders snarfblam Posted June 21, 2007 Leaders Posted June 21, 2007 DotNet does not provide a mechanism to clone objects for you. You could write a function to automate it for you using reflection (assuming you have reflection permission), but even this can be problematic (which is why C++ has copy constructors). Shallow copies will often cause conflicts with shared resources and deep copies can not be automated. Things can get hairy when you are creating memberwise clones of objects, because objects reference other objects, and the DotNet runtime has no way of knowing which referenced objects should also be duplicated and which ones should not (instead, they would only have their reference copied). For instance, if you wanted to copy an instance of your class, strings should probably not be duplicated. If you wanted to copy an instance of a Form object, controls would have to be duplicated (you can't use the same controls on two Forms at once). What's more, unmanaged resources would have to be allocated for the duplicated controls. There is no reasonable way that DotNet could possibly sort this all out for you, which is why they don't provide a built-in function to copy objects. For something that seems so simple, copying objects is actually very complex and has to be done on a case-by-case basis, which means that you have to do it yourself. Your best bet is to create a C# style "copy constructor," i.e. your constructor that accepts an object and clones itself from that. Quote [sIGPIC]e[/sIGPIC]
Arokh Posted June 21, 2007 Author Posted June 21, 2007 Ok then, thanks for the explanations. I'll write my own sub to copy the class. Quote
penfold69 Posted June 22, 2007 Posted June 22, 2007 You can (should?) also look into the ICloneable interface, which forces you to implement a Clone() function to your class (the implementation is up to you) Public Class MyClass Implements ICloneable Public StringA as String Public StringB as String Public OtherClass as MyOtherClass Public Function Clone() as MyClass Implements ICloneable.Clone Dim newClass as MyClass newClass.StringA = StringA newClass.StringB = StringB newClass.OtherClass = OtherClass.Clone() ' this nested class needs to be cloned too return newClass End Function End Class Quote
Leaders snarfblam Posted June 22, 2007 Leaders Posted June 22, 2007 Hmmm... the "copy" constructor was Microsoft's recommended technique. I'm not against use of the ICloneable interface, but unless you need to use this class in some abstract manner, neither approach has any merit over the other. I would say go with what's most intuitive. Quote [sIGPIC]e[/sIGPIC]
mskeel Posted June 27, 2007 Posted June 27, 2007 ICloneable is absolutely necesary in certain situations ICloneable is enforceable when dealing with interfaces as types. A copy constructor would not be useful in this context. A good example is generics. If you require the ability to make copies of something in a generic class, you would have to make the copies through the ICloneable methods. The where clause only supports default constructors so it would be as if the copy constructor didn't exist within the generic class. By requiring Types that use the generic class to implement ICloneable, you guarantee that some kind of copy method will be provided. Other examples might include the Factory pattern and object mocking. Quote
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.