C# get/set/properties question

Started by
21 comments, last by Zahlman 14 years, 1 month ago
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). :/
Advertisement
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.
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.

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.
This is the one that always irks me:

struct Vector2 {    public int X;    public int Y;}class Line {    public Vector2 Begin;    public Vector2 End { get; set; }}class Example {    static void Main() {        Line example;        example.Begin.X += 42; // fine        example.End.X   += 42; // explosions!    }}
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]

[OpenTK: C# OpenGL 4.4, OpenGL ES 3.0 and OpenAL 1.1. Now with Linux/KMS support!]

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)
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.
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.
Mike Popoloski | Journal | SlimDX
Ah, I misunderstood.

This topic is closed to new replies.

Advertisement