10

I'm reading a book about C# for beginners and I'm at the part "Understanding Values and References", but there is something I don't understand. What I'm seeing is that the books tries to explain this to me (and I've seen this happening in a couple of tutorial video's on Youtube as well) that the class is being used to create....an object(??) of the class. I have read the whole previous chapter where that happened too and I didn't quite understand it, assuming that it would become more clear in the following chapter. It did not become more clear, so I don't think it's a good idea to continue until I understand the concept of the stuff I explained before.

The following part is part of the book:

Remember that to initialize a reference variable such as a class, you can create a new instance of the class and assign the reference variable to the new object, like this:

Circle c = new Circle(42);
Circle copy = new Circle(99);
//Circle refc = c;
...
copy = c;

What could I do with the code in this example and why is it handy? Examples + explanation would be more than welcome. Thanks in advance!

DutchLearner
  • 335
  • 3
  • 13
  • 3
    What book is this? It will go on my "do not suggest this book to newbies"-list. I don't even see what they *might* have meant. The terminology just died from being abused by that author. – harold Jul 03 '12 at 14:27
  • 1
    Visual C# 2010 - Step by Step – DutchLearner Jul 03 '12 at 14:28
  • References refer to a point in memory, for example you have a class named Aclass, when you instantiate it `Myclass a = new Myclass()`, a couple of memory units (for example 1000,1001,1002,1003) will be reserved, and when you compare this object (a) with another object of the same class `Myclass b = new Myclass()` the memory locations are compared, it is not important what they hold as their data, a and b can both contain "1" as data, but they are not equal (talking about location in memory) – Mahdi Tahsildari Jul 03 '12 at 14:32
  • But for value types it is different, when two value types are compared, their data is the base of comparison, so `int a = 10; int b = 10; bool isEqual = a == b; //isEqual = true` – Mahdi Tahsildari Jul 03 '12 at 14:34

11 Answers11

9

By the sounds of it, you havent quite got what the book explaned:

The following to the eye reads make 2 circles sized 3 and 4, and take a copy of the first and make it 5.. except when you print it out, thats not how it worked.

class Program
{
    static void Main(string[] args)
    {

        circle a = new circle(3);
        circle b = new circle(4);
        circle d = a;
        d.Diameter = 5;

        Console.WriteLine("a is {0}", a.Diameter); // shows 5
        Console.WriteLine("b is {0}", b.Diameter); // shows 4
        Console.WriteLine("d is {0}", d.Diameter); // shows 5
    }
}

class circle
{
    public int Diameter;
    public circle(int d)
    {
        Diameter = d;
    }
}

because you didnt make a new circle for d, actually d is an alias for a, so, just as someones name is Peter, he can also be called Pete.

BugFinder
  • 16,027
  • 4
  • 35
  • 49
5

Remember that to initialize a reference variable such as a class, you can create a new instance of the class and assign the reference variable to the new object, [sic]

He's showing the difference between reference and value types. With a value type, it is already initialized.

double d;

You don't have to do anything more. With a class or reference type you have to give it an instance of an object.

Circle c; Does not have an object assigned to it yet.

d = c.Radius Error. Reference not pointing to an object. Memory access violation.

Circle c = new Circle(); Now it does.

Lee Louviere
  • 4,960
  • 28
  • 51
  • `Circle c;` does have a value assigned to it; that value is `null`. The difference between a reference and a value type is much bigger than just how they're initialized; that's really quite minor in the end. – Servy Jul 03 '12 at 15:17
  • @Servy I never said it doesn't have a value (if you call null a value). You're splitting hairs. I said, "Does not have an object assigned to it yet.". I answered the question, which is what the quote at the top is saying, that reference types have to manually assign objects to them. What more do you want from me, to write a thesis on the difference between reference and value types? Stop being so pedantic. – Lee Louviere Jul 04 '12 at 04:16
4

Well, it could be handy, and not necessary handy always to have a possiblity to assign to your type reference a new object's location. In this case, on last line copy = c;, you say that copy now points to a memory location allocated by c before, in other words, after that line they both point to the same memory location.

Travis
  • 9,959
  • 1
  • 25
  • 46
Tigran
  • 59,345
  • 8
  • 77
  • 117
  • By why do you do this in the first place: Circle c = new Circle()?? What do you say with that code and where can you use that for? – DutchLearner Jul 03 '12 at 14:29
  • @DutchLearner: I think this is just an example zipped into a couple of lines to give an idea about what is he (author) talking about. But not provide the *real* usability of this. Real usability can be determined in a real program in real code base. – Tigran Jul 03 '12 at 14:30
  • Yeah I think it is just trying to explain references objects on the stack. The example given is kinda silly, and the usefulness of this I am sure exists somewhere, its just not common. – ledgeJumper Jul 03 '12 at 14:32
  • It's pretty common, instead. I mean, pretty common switching object's referencies (for 1000+ reasons), but not in *this* way, like explained. But I think, it's also hard to explain *real use* of it in a couple of lines, may be that is a problem. – Tigran Jul 03 '12 at 14:38
  • 1
    `Field a = new Field(); Field b = new Field(); Field focused = a; ... b_OnClick(...) { focused = b; }` – Lee Louviere Jul 03 '12 at 14:41
  • Ok, but **why** I would like to do this.. there are dozen of examples that can come to mind, to make it clear to a reader, why he has to use this, it's not so easy, **imo**. – Tigran Jul 03 '12 at 15:05
3

It's rather complicated to give you a crash course in object-oriented programming but that's it what you need at this point: you currently need an understanding of OO-programming which is a programming paradigm that many programming languages have in common of course also C#.

The issue you are describing in your post above is the following:

In oo-prgramming you are writing classes that consist of (roughly) fields and methods. These classes have a static character and are existing during the development time of your application (Please don't get confused with the word static I am using in here and the keyword 'static'). During runtime of your application you can use these static *classes* to create objects of these classes which means a particular class serves as a building plan for an arbitrary number of objects that are all identical. In contrast to classes these objects are also called instances of a class and are only existing during runtime of your application. Objects are dynamic.

Just very short: When you have a class

class House {

// ...
}

you have an static description of a house which you can use to create dynamic *objects* i.e. houses. You are doing this (in C# and other modern languages like Java) with the so-called new-operator:

House house = new House();

What you are doing here is to declare a variable of type House. A type you have definded on your own with the class House. It's this part:

House house;

So far it's only a variable of type House which does nothing. The term which is important here is that it points to nothing and this nothing is referred to as null.

Then you can create an instance of this class (a dynamic object) with the following syntax:

house = new House();

Now you've created an object and let your variable house point to that object. From now on you can refer to this object with the variable house.

I am telling you this to point out one important issue you mentioned in your post above: The difference of value types and refernce types.

What you've done in the previous lines is you've created a new variable that points to an object. This is (roughly again) called a reference type. In contrast to that you have for example primitive types like int, byte, short etc.

With

int i = 4;

your are again declaring a variable. But this time the variable directly holds it's value rather than pointing to it. This is referred to as a value type.

The difference between value types and reference types is very important for example when you pass such variables as parameter into methods.

marc wellman
  • 5,261
  • 5
  • 28
  • 55
2

I'll try to fix up that quote, because that's just terrible.

Original:

Remember that to initialize a reference variable such as a class, you can create a new instance of the class and assign the reference variable to the new object, like this:

Fixed:

Remember that to initialize a variable of a reference type, you can create a new instance of the type of that variable and change the variable to point to the new object, like this:

Although why that should be something you should remember, I don't know. Yes, you can create several references to the same object, and that can be useful on its own, but it doesn't strike me as a particularly useful initialization strategy.

Fixed even better:

You can make variables of reference types refer to the same instance, but remember that the variables itself are not aliases so overwriting one does not change the other.

harold
  • 53,069
  • 5
  • 75
  • 140
1

You can think of a class as a schema for data, like a specification or a blueprint. When you use the "new" keyword, you are telling the computer to use that blueprint to make an object for you. An object is a concrete instance of that class.

So if you have a blueprint (a class definition) you can call new as many times as you want to produce as many instances of that class as you want. The same way that if you have a blueprint for a car you can make as many copies of that car as you want (given enough material).

So doing:

Circle c = new Circle(42);
Circle copy = new Circle(99);

Is telling the computer to use the Circle class definition and instance two objects (so you have two circles that exist in your computer's memory). These are different objects with different properties (one has radius 42 and the other 99). They are being assigned into the variables c and copy.

The last line of your code where you do copy = c; is putting the circle pointed to by the variable c into the variable copy.

deemen
  • 118
  • 6
1

The class definition is the blue print. Think of it like a house. Every time you instantiate an object Circle c = new Circle(42) you are constructing a house with that blue print. Each house has an address on the street (address in memory).

Every variable you have is like a slip of paper that lists the address of the house. So you build a blue 2 story house at 123 main street, and write 123 main street on a piece of paper and label that paper 'A'. Next you build a red 4 story house at 456 King Street, and write that address down on paper and label that paper 'B'. Next, you get a piece of paper and write down the address of the first house you made (123 Main Street) and label that paper 'C'.

You then go to a painter and ask him to paint a house yellow. You give him the slip of paper 'C'.

There are only two houses in our example. Since C and A "point" to the same address they now point to a yellow house.

House a = new House( blue, 2 );
House b = new House( red, 4 );
House c = a;
c.Color = yellow;
//Now a.Color is yellow as well
James
  • 2,335
  • 2
  • 23
  • 33
1

A variable is not an object, it is only a reference to an object. So, for instance, in the following example, there are two variables that both reference the same object:

Label label1 = new Label();
Label label2 = label1;
label1.Text = "1";
label2.Text = "2";

After executing that code, you will see that label1.Text equals "2" rather than "1". That is because they both reference the same Label object, so when you set label2.Text, it will change for both variables. If, however, you instantiated two separate label objects, the result would be different, for instance:

Label label1 = new Label();
Label label2 = new Label();
label1.Text = "1";
label2.Text = "2";

In this second example, each variable points to a different Label object (i.e. a different instance of the Label class). Therefore, after running this code, label1.Text will equal "1" and label2.Text will equal "2", as you would expect.

There are good reasons why both of these options are important and available to you. For instance, lets say you want to make a method that sets the Text property of a Label, for instance:

void SetLabelText(Label labelToSet)
{
    labelToSet.Text = "text";
}

And you may call the method like this:

Label label1 = new Label();
SetLabelText(label1);

In this case, the labelToSet variable in the SetLabelText method will reference the same object as the label1 variable, so when 'SetLabelText sets labelToSet.Text to "text", it's not creating a new Label, it's just setting the text on an existing Label object that was passed as a parameter to the method, which is exactly what you would want to happen.

Since any variable may be set to either a new object or an existing object, it is considered "null" until it has been assigned to an object. As I said at first, the variable is not the object, it's just the reference to the object. If a variable references no object at all (it's initial state), it is null and will throw an exception if you try to use it. For instance:

Label label1; 
label1.Text = "1";  // Throws a null reference exception

You can declare as many variables as you want, but they will all be null until you actually instantiate at least one object and set them to it. To instantiate an object (i.e. create a new instance of a class), you must use the new keyword (e.g. new Label()).

However, everything I've said so far is only true of "Reference Types" (class). That is not the case with "Value Types" (struct). When you declare a variable as a value type, for all practical purposes, it is actually the object. Many simple data types such as int are value types. So for instance:

int x;
int y;
x = 1;
y = x;
y = 2;

After running the above code, x will equal 1 and y will equal 2. Setting y = x does not cause y to reference the same object as x. Rather, it copies the value from x to y, thereby creating a new value type object.

Steven Doggart
  • 41,612
  • 8
  • 64
  • 99
0

If we refer to human in this context the class defines what is a human and what it can do (it's members like height, width etc. and it's methods eat(), drink() etc.) and a object represents the actual human (a person named Andrew that has a height a width can eat and drink)

Rzv.im
  • 888
  • 7
  • 12
0

Please correct me if I am wrong, but when i look at the code I see two objects being created and pointing at a value is their own memory locations.

The copy = c; line just say that the copy object is not going to point the the memory location of the c object rather than the one it was first set to.

ledgeJumper
  • 3,391
  • 14
  • 42
  • 90
0

In the example you provided, and as is the case with many examples provided by books, you are seeing the most basic case. It is hard to understand the best way to use a feature like this until you actually get into greater depth with the code.

I don't know if this is exactly correct, but the way that I would use something like this is:

private double GetArea(Circle c)
{
     //this will be a default circle should the passed in circle be invalid
     Circle toCalc = new Circle(5);

     //check to make sure c is valid
     if(c != null)
          toCalc = c;

     return Math.pow(toCalc.Radius, 2) * Math.Pi;
}

Since toCalc is a class and not a primitive data type it must be initialized in order for the code to compile. If it isn't initialized, the compiler will give you some error like "toCalc may not be initialized."

tcannon91
  • 217
  • 1
  • 2
  • 9