Kavet Kerek
Kavet Kerek

Reputation: 1315

Do C# properties hide instance variables or is something deeper going on?

Consider the class:

public class foo
{
    public object newObject
    {
        get
        {
            return new object();
        }
    }
}

According to MSDN:

Properties are members that provide a flexible mechanism to read, write, or compute the values of private fields. Properties can be used as though they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily

And:

Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code.

A get property accessor is used to return the property value, and a set accessor is used to assign a new value. These accessors can have different access levels. For more information, see Accessor Accessibility.

The value keyword is used to define the value being assigned by the set indexer.

Properties that do not implement a set method are read only. while still providing the safety and flexibility of methods.

Does this therefore mean that at some point in time the value of the newObject property has a reference to the returned new object?

edit removed readonly from property

edit2 also would like to clarify that this is not the best use for a property but its done to try and illustrate the question more effectively.

Upvotes: 3

Views: 2050

Answers (4)

Martin Liversage
Martin Liversage

Reputation: 106926

You return a new object on each access to the property and that is not the expected behavior of properties. Instead you should return the same value each time (e.g. a value stored in a field). A property getter is simply glorified syntax for a method that returns a value. Your code compiles into something like this (the compiler creates a getter by prefixing the property name with get_ which is then emitted as IL):

public class foo
{
    public object get_newObject()
    {
        return new object();
    }
}

Each call to the getter will create a new object that foo doesn't know about or has access to.

Does this therefore mean that at some point in time the value of the newObject property has a reference to the returned new object?

No.


Property using a backing field:

class Foo {

  readonly Object bar = new Object();

  public Object Bar { get { return this.bar; } }

}

Using automatic properties:

class Foo {

  public Foo() {
    Bar = new Object();
  }

  public Object Bar { get; private set; }

}

A property is accessed using the same easy syntax as a public field. However, by using a property you can add code to the getter and the setter allowing you to do stuff like lazy loading in the getter or validation in the setter (and much more).

Upvotes: 10

Iridium
Iridium

Reputation: 23731

Properties in C# are "syntactic sugar". The code within the get block of a property is in fact put into a hidden get_PropertyName() method, and the set block into a hidden set_PropertyName() method. In the case of your code, the following method will be created:

public object get_newObject()
{
    return new object();
}

You can see these hidden methods if you view the compiled assembly using Reflector, or ildasm.

When the property is used, the C# compiler converts any "get" accesses of your property into calls of the get_newObject() method. As an example:

If you were to write the following:

var foo = new foo();
var aNewObject = foo.newObject;

The compiler would convert that to:

var foo = new foo();
var aNewObject = foo.get_newObject();

So, in answer to your other question, the newly created object returned when someone "gets" the property won't be stored within your foo instance, the caller will simply get a new object every time.

Upvotes: 1

Jon Senchyna
Jon Senchyna

Reputation: 8047

Under the hood, your property will simply be calling a function named get_newObject() that looks like this:

public object get_newObject()
{
    return new object();
}

Since that is the case, it will always return a new object every time it is invoked.

If you want to retain a reference to the object, then I would recommend creating a private field to hold the data and having the property access that field, like so:

private object myObject;
public object newObject
{
    if(myObject == null)
    {
        myObject  = new object();
    }
    return myObject;
}

Since your property doesn't define set, and your field is private, newObject is basically eradonly outside of the containing class.

Upvotes: 1

Davin Tryon
Davin Tryon

Reputation: 67336

Not exactly. Properties are just syntactic sugar so that you don't have to write accessor methods (like Java).

So this:

private int _myInteger;
public int MyInteger
{
    get { return _myInteger; }
    set { _myInteger = value; }
}

is equivilant to this:

private int _myInteger;
public int GetMyInteger()
{
    return _myInteger;
}

public void SetMyInteger(int value)
{
   _myInteger = value;
}

and it gets better with this, which is also equivilant:

public int MyInteger { get; set; }

Upvotes: 0

Related Questions