Sign in to follow this  
Timptation

C# get/set/properties question

Recommended Posts

Reading about C#'s auto-implemented properties, you can write a line such as: public int ID { get; set; } Can someone explain to me how this is useful? You can't place a breakpoint on that, so without that benefit, I might as well be using a public field... How is this better than the standard get/set like this: private int m_id = -1; public int ID { get { return m_id; } set { m_id = value; } } ???

Share this post


Link to post
Share on other sites
Brevity, and because fields can't be used (and thus implemented as part of) interfaces. And because for a few select things, a property doesn't quite behave like a field, so refactoring from a field to a property (once you need to) isn't ideal.

In general though, the 'omg this is the best thing since sliced bread!' feeling I get from some about the feature is... overblown to say the least.

Share this post


Link to post
Share on other sites
Well... The first is shorter and is clear that it works like most properties do.

Also how likely are you to need to breakpoint the getter or a setter of the code you provided? Is there a very high likelihood that it will not work?

I feel it's sort of asking the question "Why do we have x++; when we have x = x + 1;?"

Share this post


Link to post
Share on other sites
Its only use is less typing.

Why would you want to put a breakppoint at _field = value; ?

Changing public field to a set/get later on break or changes your interface because get/set are functions and a public field... well, it is just that.

Share this post


Link to post
Share on other sites
The standard reasoning behind using properties vs. fields is that you can change the internals of a property without breaking the public interface of your class. So even if you only need trivial access right now, using a property is just good future proofing.

Since it's recommended that you always use public properties, more and more language and API features are being developed around them as opposed to fields, with automatic properties being an example of one. They simply reduce the amount of code to get a trivial property implemented.

Share this post


Link to post
Share on other sites
I think everyone may have misunderstood what I meant. I don't actually want to use a public field. I'm saying I don't see the point of the auto property because it seems to do exactly the same thing as just having a public field. The benefit of the get/set functionality is that you have a simple one-stop-shop for the altering of data (when it comes to debugging), and like you said, one place to change the functionality if you need to later. Yes, you can make it easier to rewrite the functionality later by expanding to a manually implemented property, however you still have lost the ability to debug the data field if you use this auto property. It just seems like a lazy/bad idea to me. Someone mentioned that you can use this in an interface, which does seem interesting, but then I just have to wonder why interfaces don't support their own members anyway... (this is coming from someone who has been working with C++ for years now BTW, if that helps you see my viewpoint).

Share this post


Link to post
Share on other sites
Quote:
Original post by Timptation
I don't actually want to use a public field. I'm saying I don't see the point of the auto property because it seems to do exactly the same thing as just having a public field.
But a public property is not the same as public field.

A number of things in the base class library (for example, the property grid control in WinForms and the XmlSerializer class) only work with properties. You could, perhaps, make the argument that these things should work with public fields as well as public properties, but that's a design decision that Microsoft has made.

If I had an auto-implemented property and I want to be able to put a breakpoint on the get/set, I'd just manually expand it out into a full property for the purpose of that debugging session.

Share this post


Link to post
Share on other sites
Quote:
Original post by Timptation
The benefit of the get/set functionality is that you have a simple one-stop-shop for the altering of data (when it comes to debugging)


That is a simple view of properties. Their primary benefit is looking and behaving like a field when in fact they're not backed by any (class) data.

Oh, and auto-properties allow for more easily specifying a 'field' that has different visibility levels for get/set. (just another benefit I forgot)

Quote:

but then I just have to wonder why interfaces don't support their own members anyway...


Because there's no good way to determine initialization order or virtual dispatch resolution of arbitrary multiple inheritance hierarchies in a nominative type system.

Share this post


Link to post
Share on other sites
I understand the difference between a field and a property. I guess this just comes down to "auto-properties reduce typing and improve readability", and my annoyance with having to rewrite/compile for a particular debug session. Maybe I'm comparing it to having to recompile a .h in C++, which can end up costing you a good amount of time if its included everywhere in a large project. My understanding is that C# is a bit better about that though...

edit- Oh, and the C++ example I'm thinking of is when a set function declaration and definition is written all on one line, so stepping never really gets the chance to enter the local scope, making it harder to debug. Thus, you have to expand the body vertically, meaning a recompile.

[Edited by - Timptation on February 19, 2010 12:42:31 AM]

Share this post


Link to post
Share on other sites
One of the use of the auto complete property is to set the level of access from
another class or inherit.


///
///Only the father class can modify the value
///
public int Count
{
get;
private set;
}
///
/// inherit class can modify the value
///
public int Count
{
get;
protected set;
}





Also if you drag the property to the watch window, it will automatic show the get value like:


public void Blabla()
{
MyClass c = new MyClass();
c.Count; //drag this to the watch window
}



A normal use is to create a class that inherit from List<> and then create a property with a "protected set" and a "public get" like the first example.


Edit: code tag add

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
because fields can't be used (and thus implemented as part of) interfaces. And because for a few select things, a property doesn't quite behave like a field


Such as? :(

Quote:
so refactoring from a field to a property (once you need to) isn't ideal.


But if, indeed,

Quote:
Their primary benefit is looking and behaving like a field when in fact they [could be anything]


, then what exactly is going on here? I thought the whole point was to be able to switch from using a field to a property upon determining that it's necessary, and not have to change any external code. If that doesn't work, it seems like it's only syntactic sugar (and a relatively ridiculous bit of it at that) which misses a golden opportunity. And if it does work, then the { get; set; } part seems useless as-is (wait until it's at least as complicated as { get; private set; } or whatever). :/

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by Telastyn
because fields can't be used (and thus implemented as part of) interfaces. And because for a few select things, a property doesn't quite behave like a field


Such as? :(
Take the following:

class Foo
{
public int Field;
public int Property { get; set; }
}

class Bar
{
public static void DoWork(out int something)
{
something = 123;
}

public static void Main()
{
var f = new Foo();
DoWork(out f.Field); // works
DoWork(out f.Property); // doesn't compile
}
}

So you can't just change a field to a property and expect it to work.

And as I mentioned above, XmlSerializer and the PropertyGrid control only works with properties, not fields.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by Telastyn
because fields can't be used (and thus implemented as part of) interfaces. And because for a few select things, a property doesn't quite behave like a field


Such as? :(


If user-made reflection is looking for one or the other. Attributes are also occasionally set to only be allowed on one or the other, in addition to Codeka's example.

It is a very rare subset, but I was playing devil's advocate for using auto-properties, even for the trivial case.

Share this post


Link to post
Share on other sites
Hmm. Sounds like the usual advice of "do simple things when you can and fancier things when you have to" still applies, at least. :) Thanks for the examples.

Share this post


Link to post
Share on other sites
Also, consider this:

class Parent
{
public virtual int Id { get; protected set; }
}

class Child : Parent
{
public override int Id
{
get
{
if (...)
return ...;
else
return base.Id;
}
protected set
{
base.Id = value;
}
}
}



You cannot do this with fields. In fact, this is one reason why public interfaces should never expose naked fields. Once you have provided a field, you are bound to this implementation for life (while you can internal implementations for properties without issue.)

Auto properties are just syntactic sugar, so that you don't need to write:

public class Parent
{
int id;
public int Id { get { return id; } set { id = value; } }
}


for trivial properties. This sugar is also necessary for anonymous classes.

Off-topic: features in C# tend to have strong synergy. For example, anonymous delegates and Nullable<T> in C# 2.0, auto properties and extension methods in C# 3.0. Useful on their own, but put them together and they become powerful: they give you Linq, which is more than the sum of all parts.

This synergy is what makes C# such a nice language. Other wide-spread languages, like C++ or Obj-C, lack this tight design and are not nearly as nice to use.
[/source]

Share this post


Link to post
Share on other sites
Quote:
Original post by Fiddler
Once you have provided a field, you are bound to this implementation for life (while you can internal implementations for properties without issue.)



How exactly is changing from a field to a property any sort of breaking change to external consumers?

(besides the corner cases that the past half dozen or so posts have shown)

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
(besides the corner cases that the past half dozen or so posts have shown)


"How is it a breaking change if it's not a breaking change?"

And I still have a possible answer for that: At the ABI level. I'm bored enough to test this right now. EDIT: Yep. They'll need to recompile.

Share this post


Link to post
Share on other sites
Yes. Suppose you have application Test, which relies on a class library called Library. Library exposes the following type:

public class Exposed
{
public int Field;

public Exposed()
{
Field = 10;
}
}



Your application looks like this:

class Program
{
public static void Main()
{
Exposed e = new Exposed();
Console.WriteLine(e.Field);
}
}



Now you take your application and the Library.dll and deploy it. When run, you get the expected output of 10.

Now let's say after a few weeks you need your application to output a different value, say 20. You go back to Library, adjust the constructor to initialize Field to 20, and then copy the DLL onto the deployed machine. Test picks up the changes automatically without recompiling, and correctly outputs 20.

Now let's say you need to change from a field to a property so that you can return a value loaded from a database or something. The Exposed type now looks like this:

public class Exposed
{
public int Field
{
get { return 3 * 4 + 1; } // some calculated value
}

public Exposed()
{
}
}



Compile and distribute the DLL. Bam! The application fails because it can't find the field it's looking for.

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
This is the one that always irks me:

*** Source Snippet Removed ***


Wow, it doesn't translate += for a property into a get/set pair? Epic fail. :(

/me feels increased motivation to target .NET bytecode with that language design...

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by MaulingMonkey
This is the one that always irks me:

*** Source Snippet Removed ***


Wow, it doesn't translate += for a property into a get/set pair? Epic fail. :(

/me feels increased motivation to target .NET bytecode with that language design...


No, you missed the point entirely. He's accessing an inner property of the Line. Since Vector2 is a value type, its getter returns a copy, and therefore the access of member X would only update the copied version, not the original. Therefore, C# marks this as an error for you so that you don't get confused as to why the value isn't updating.

Share this post


Link to post
Share on other sites
Ahh, I see what you're saying now.

It does kind of suck that 'ref' can apply to parameters but not to the return value. (Of course, 'in' and 'out' would be meaningless for a return value.)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this