NP143 struct
http://www.c-sharpcorner.com/UploadFile/rmcochran/chsarp_memory401152006094206AM/chsarp_memory4.aspx
In the above website following program is given. What is the meaning of Bill.LeftShoe = new Shoe(); & Bill.RightShoe = new Shoe(); highlighted in yellow in the program.
Please explain the meaning.
Thank you
using System;
public struct Shoe
{
public string Color;
}
public class Dude
{
public string Name;
public Shoe RightShoe;
public Shoe LeftShoe;
/*
public Dude CopyDude()
{
Dude newPerson = new Dude();
newPerson.Name = Name;
newPerson.LeftShoe = LeftShoe;
newPerson.RightShoe = RightShoe;
return newPerson;
}
*/
public override string ToString()
{
return (Name + " : Dude!, I have a "
+ RightShoe.Color + " shoe on my right foot, and a " + LeftShoe.Color + " on my left foot.");
}
}
class x
{
public static void Main()
{
Dude Bill = new Dude();
Bill.Name = "Bill";
Bill.LeftShoe.Color = Bill.RightShoe.Color = "Blue";
//Bill.LeftShoe = new Shoe();
//Bill.RightShoe = new Shoe();
//Dude Ted = Bill.CopyDude();
//OR
Dude Ted = new Dude();
//Bill.CopyDude();
Ted.Name = "Ted";
Ted.LeftShoe.Color = Ted.RightShoe.Color = "Red";
Console.WriteLine(Bill.ToString());
Console.WriteLine(Ted.ToString());
}
}
/*
Bill : Dude!, I have a Blue shoe on my right foot, and a Blue on my left foot.
Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot.
*/
AlanPosted Sep 2, 2008, 5:09 AM
Well, LeftShoe and RightShoe are public fields of the Dude class and Bill is an instance of that class.
The two fields are of type Shoe (which is a value type) and the lines marked in yellow are setting them to new Shoe instances.
When you use the 'new' operator with a value type, this sets all its fields to their default values and so Shoe.Color is set to null which is the default value for a string.
Those lines are actually unnecessary in this program - if you take them out it will still compile and run fine.
This is because when you create a new Dude object, all its fields (and hence the fields of those fields if they are non-primitive structs) are set to their default values anyway.
Posted Sep 6, 2008, 8:53 AM
Excellent explanation. Thank you very much for help.
AlanPosted Sep 6, 2008, 8:30 AM
You're roughly right though the following is a more accurate description of what 'new' does (and the order in which it does it) when used with a constructor of a reference type (Foo let's say).
1. It allocates sufficient memory on the heap to store the instance fields of Foo plus a further 8 bytes overhead (on a 32 bit system).
2. It initializes the overhead (don't worry about what this entails).
3. It sets all the bytes used to store the fields to 0 (the zero byte). This means that all the fields are initially set to their default values (null for a reference type, zero for numeric types, false for bool, '\0' for char etc.)
4. If any of the fields have initial values assigned to them (for example private int i = 3;), it sets the fields to those values.
5. It then calls Foo's constructor which calls its parent's constructor and so on all the way up to System.Object's constructor. The code in these constructors is then executed as the stack unwinds finishing with the code in Foo's constructor.
6. It returns a reference to the newly created object.
In practice, you seldom need to remember all this. All you need to know is that 'new' causes a new Foo object to be created and returns a reference to it.
Moving on to your second point, you only need to use code of this pattern:
SomeType someVariable = new SomeType(); // or whatever
if someVariable hasn't been declared before. This might be the case if someVariable were a local variable or if it were a field which you were initializing where it's declared, rather than using a separate assignment statement.
The following statement doesn't fall into this pattern and is therefore invalid syntax:
Shoe Bill.LeftShoe = new Shoe();
because the LeftShow field has been declared before within the Dude class as being of type Shoe and Bill is a reference to a Dude object which has already been created.
However, there's nothing wrong with a simple assignment statement such as this:
Bill.LeftShoe = new Shoe();
Posted Sep 5, 2008, 1:58 PM
So when we declare Employee myAssistant = new Employee(); in which new Employee() is doing following 3 jobs:
1) It creates an Employee object which is myAssistant
2) It allocates the needed memory to hold myAssistant
3) It constructs Employee constructor method
I wish to know whether my understanding is correct.
Also please explain why it is not correct to say so.
Shoe Bill.LeftShoe = new Shoe();
Mahesh ChandPosted Sep 5, 2008, 9:15 AM
Posted Sep 4, 2008, 3:52 PM
A book is explaining about Declaring Objects.
Employee myAssistant = new Employee();.
There is a sentence:
“The last portion of the statement, Employee() is the name of a method that constructs an Employee object”. Employee() is a constructor method.
I can understand the meaning of the “Employee() is a constructor method”. What is meant by “constructs an Employee object” (highlighted in yellow)?
AlanPosted Sep 4, 2008, 2:06 PM
Because if you have this line:
Bill.LeftShoe = new Shoe();
you're assigning a new Shoe object to the field Bill.LeftShoe.
This is the same as:
Shoe shoe = new Shoe();
Bill.LeftShoe = shoe;
If Bill.LeftShoe were on the RHS i.e:
shoe = Bill.LeftShoe;
then you'd be assigning what's in Bill.LeftShoe (currently null) to the Shoe variable, shoe.
Posted Sep 4, 2008, 12:29 PM
Please explain the reason why Bill.LeftShoe must come in the LHS.
AlanPosted Sep 4, 2008, 9:25 AM
Not quite, but it can be written like this:
Shoe shoe = new Shoe();
Bill.LeftShoe = shoe;
Posted Sep 4, 2008, 6:28 AM
That means code Bill.LeftShoe = new Shoe(); can be written as follows:
Shoe shoe = new Shoe();
shoe = Bill.LeftShoe;
AlanPosted Sep 3, 2008, 7:24 PM
You've explained it yourself, Maha, with your last paragraph:
"For example if we say Shoe shoe = new Shoe(); new sets aside enough memory to hold shoe. Whereas Shoe() is the name of a method that constructs an Shoe object."
The only thing I'd add is that the method is, of course, the Shoe constructor and once the object has been constructed a reference to it is then assigned to the field Bill.LeftShoe.
Posted Sep 3, 2008, 5:38 PM
Thank you very much for explanation.
Bill.LeftShoe = new Shoe();
Above code is confusing me. Bill is an instance of Dude and LeftShoe is a field of a Dude class. Bill.LeftShoe is giving new Shoe instances. Is there anything to explain please explain the meaning of it?
For example if we say Shoe shoe = new Shoe(); new sets aside enough memory to hold shoe. Whereas Shoe() is the name of a method that constructs an Shoe object.
AlanPosted Sep 2, 2008, 6:41 PM
If you change the program back to how it was originally and make Shoe a class rather than a struct, then you will need to change the Dude.CopyDude() method to the following in order for the program to give the same output as before:
public Dude CopyDude()
{
Dude newPerson = new Dude();
newPerson.Name = Name;
newPerson.LeftShoe = new Shoe();
newPerson.LeftShoe.Color = LeftShoe.Color;
newPerson.RightShoe = new Shoe();
newPerson.RightShoe.Color = RightShoe.Color;
return newPerson;
}
It's no longer enough to set newPerson.LeftShoe to the current object's LeftShoe property If you do that then both properties will point to the same Shoe object and so changing the color of newPerson's LeftShoe will automatically change the color of the current object's LeftShoe - and both LeftShoes will end up red!
A similar argument applies to the RightShoe property.
You therefore have to create new Shoe objects and set the Color properties individually.
This doesn't happen when Shoe is a struct because it's the value of the struct that's copied (i.e. the value of the Color string) not a reference to where the Shoe object resides on the heap.
Posted Sep 2, 2008, 5:16 PM
If we change into class instead of struct (highlighted in red) what are the changes must be done in the program in order to execute it to give following output? Please explain the changes.
Bill: Dude!, I have a Blue shoe on my right foot, and a Blue on my left foot
Ted: Dude!, I have a Red shoe on my right foot, and a Red on my left foot
AlanPosted Sep 2, 2008, 3:41 PM
In that case, you're just creating a new Dude object in the usual way (i.e. using 'new' rather than a 'Copy' method) and then setting its properties.
As you're still setting all the properties manually (previously they were all reset after being copied from Bill), the output is the same as before.
I think the purpose of this program was just to show how you might go about cloning an object. I don't think there's any deeper significance than that.
Posted Sep 2, 2008, 1:22 PM
I am sorry I have forgotten to mention. While removing the code highlighted in blue you have to comment out Dude Ted = Bill.CopyDude(); as well. Under this circumstances program is executing well.
Instead of Dude Ted = Bill.CopyDude(); can be written as follows
Dude Ted = new Dude();
Bill.CopyDude();
Highlighted in green. This won’t change the output, how can this be explained?
AlanPosted Sep 2, 2008, 12:04 PM
Well, I had in mind the Dude object referenced by the variable Bill but that statement would be true for any Dude object including the one referenced by newPerson.
The line:
Dude newPerson = new Dude();
is within the Dude.CopyDude() method whose purpose is to clone a Dude object. In order to do this, you have to begin by creating a new Dude object (as the above line does) and then set its fields to the same values as the fields of the object which is being copied.
I didn't follow what you meant about the code still working if you removed the code highlighted in blue (i.e. the CopyDude() method) because, if you do, then the compiler will complain about this line:
Dude Ted = Bill.CopyDude();
in the Main() method.
Posted Sep 2, 2008, 7:40 AM
In the last sentence
This is because when you create a new Dude object, all its fields (and hence the fields of those fields if they are non-primitive structs) are set to their default values anyway.
Which Dude object you mean because Dude objects are created in two places one object is Bill and other object is newPerson.
Also what is the reason for the code Dude newPerson = new Dude();?
Without codes highlighted in blue, program is executing well, so what is purpose of having that codes?