C# Automatic Properties: Semantic changes to help cope with poor syntax?

Steve Eichert and Bart de Smet both posted last November about a new C# feature: Automatic Properties.

The language enhancement will convert code like this in a class definition:

public string MyProperty { get; set; }

 

Into something like this:

private string myProperty;
public string MyProperty
{
get{return myProperty;}
set{myProperty = value;}
}

I’ve got to admit that I view this with a few misgivings. Primarily, I worry about how to interpret MyProperty in an abstract or virtual class. Will there be an implementation generated for an abstract class? Is the code generation skipped if the property is virtual? At first glance, it doesn’t seem to enhance to the clarity of the language. Currently { get; set; } has only one meaning – no implementation provided! Now we will have to look at the context of the declaration to know if it really means that at all! What will this do for those porting C# 2 code to C# 3?

Some of the commenters on Steve’s post suggested adding a new keyword to the language so that you could get code like this:

public property string MyProperty;

or

public readonly property string MyProperty;

It’s definitely less ambiguous than the syntax proposed by Anders Hejlsberg. I just wonder why it is necessary at all. What encapsulation is provided by such a feature? What are you getting? A property provides a degree of encapsulation to a field, which is why people declare properties to wrap fields. It allows you to add validation or some other source for the data. I have no objection to the C# team providing as much syntactic sugar as they like, but when they change the semantics of the language, I think they should definitely look before they leap! The only advantage to be gained from it is less typing. Hejlsberg must really hate typing! You can’t define a field in an interface so the empty property anti-pattern is obligatory in C# 2.0. Why enshrine it in the language though?

Are empty properties another one of those half-understood injunctions that developers pay lip service to? (I lump configuration in this category) After all, the only point of a property is if you do something in it other than turn a private variable into a public one. Why not make fields declarable in interfaces? That way, we’d only have to encapsulate them if they weren’t stored in the class or if we wanted to do something with them prior to changing state? It wouldn’t change the semantics of the language either, and it would be backwards compatible.

If I was obliged to add Automatic Properties to the language I might be tempted to make use of an attribute to annotate a field instead:

[Property("MyProperty")] private string myField;

Attributes are an excellent way to pass on hints to the compiler. They are more versatile than keywords, and wouldn’t require syntax changes. Keeping the language definition stable would probably please tool vendors too.

About these ads

19 comments

  1. The issue is that they are changing the way the language works – syntactic changes just give us a shorthand. With this change the whole meaning of an established syntax is changed. That is more likely to create headaches. For headaches, see Ruby. ;^}

  2. What I don’t like about this is that it forces camelCasing on people whether they want it or not. Personally, I feel that all class-level variables need a prefix that indicates that it’s a class-level variable and this just destroys that in practice.

    I’m sure the compiler will be smart enough to handle. I like your attribute idea, and I would go further and have it be the other way around like this:

    [ImpliedVariable(name="m_strInstance", initialize="string.Empty")]
    public string InstanceString { get; set; }

    This would generate the following code:

    private string m_strInstance = string.Empty;
    public string InstanceString
    { get { return m_strInstance; }
    set { m_strInstance = string.Empty; } }

  3. you can always type
    prop and then press tab to get the full field and property or propa if you only want the get to be generated…

  4. Hi Payton,
    I think your idea is better than mine. Either way, though, it is more consistent using attributes. It does seem to me that the syntax of the language is subject to revision at the slightest whim of the language designers. We’re caught between the kind of linguistic stasis of a standardised language (C++ was only updated once in the years that I used it) to the churn of an unstandardised proprietary language like VB.

    Which is better? To have a clean and consistent language or one with a hundred ad-hoc syntax sweetners to cope with common idioms? (cf nullable types)

    Wasn’t syntactic bloat also a criticism levelled at PL1?

  5. This:
    “public string MyProperty { get; set; }”

    Is not a valid C# in any scenario.
    In a abstract class, you will have:

    public abstract string MyProperty { get; set; }

    Which is different.

    The is no syntax ambiguity.

  6. The reason using properties instead of fields is often useful is because you can later modify your property getter / setter without requiring that clients of your code be rebuilt. If you change a field to a property, you will have to rebuild all client code (often not possible if your code is a public library).

    Whether this warrants more syntactic sugar is debatable, and I certainly don’t like the proposed way of doing things. I’d much prefer:

    public property string MyString { get; set; }

    If you need to customize the backing field then write it. This is analogous to how events work:

    public event EventHandler MyEvent; //uses the default backing store

    public event EventHandler MyEvent
    { //use whatever backing store you want
    add {}
    remove {}
    }

    My 2c,
    Kent

  7. I loved C# when it came out. I loved that most common mistakes made in C++ where detected at compile time on C#. The ifs finally had to contain boolean expressions…

    The only things missing were the generics and unsigned types on the framework. We no have the first but unfortunately we are not going to have the second one because of some other languages. Why the hell do we have to use int for the age of a person? I wish I didn’t have to validate it…

    Anyway, I think these last changes, like nameless delegates, will only confuse people. C# will end up like C++, too confusing…

    Antao

  8. Whoops, I meant I prefer this syntax:

    public property string MyProperty;
    -or-
    public readonly property string MyProperty;

    because it is much more similar to how events are declared by default. And you could control serialization in the same way:

    [field: NonSerialized]
    public property string MyProperty;

    I guess the difference comes about when you explicitly implement the property because you drop the “property” keyword, whereas you don’t drop the “event” keyword when you explicitly implement an event:

    public string MyProperty
    {
    get { … }
    set { … }
    }

    Kent

  9. Hi Antao,

    I know what you mean. I used to pride myself on my pointer arithmetic. But on reflection, that’s madness. I drive a car with an automatic gearbox because I’m confidant that it can change gears better than I can. The same ought to be true for the mindless drudgery of keeping track of objects. The nicest language ought to be the most transparent – the one where you have to think least of all about what the likely syntax fora given construct ought to be. When the language designers start adding non-intuitive syntaxes to save on typing, something’s wrong.

    As Ayende pointed out, there is a disambiguation in C# for non-implemented abstract properties – the abstract keyword. Although that is not necessary for interfaces (I have to admit I still think of interfaces as pure abstract classes, even though they’re not in C#). I can’t help feeling that if this trend of gilding the lily continues the language will be a mass of special cases, with a different thought process for each construct. the end result will be a continual cognitive dissonance, which will put people off it altogether.

    I admit I’m being a little alarmist, but I still think that clarity ought to triumph over brevity!

    As for unsigned types, I presume you mean that if you use System.Uint32 you are violating CLS compliance? I also wonder why they never included that as a requirement for the CLS… Of course if that is not an issue, then you can use it with impunity :-)

  10. Even though I’m forced to use primarily C# in my work, I’m a VB.Net syntax lover. So I look at this from a slightly different perspective, I think.

    I like both the attribute idea and adding the “property” keyword idea. I think the attribute idea is more flexible in that hopefully the Property attribute could be extended so that we could create our own property implementations (e.g. adding INotifyPropertyChanged). However, I think the “property” keyword would be more consistent with the way C# works now (when comparing it to the “event” keyword).

    In any case, I think the original proposed idea is awful. It seems that Ayende Rahien (no offense) is the only commenter to support it so far, so I hope it doesn’t stick.

    When I try to give definition to what is going on with the proposed way of adding automatic properties, I come up with “If the Member is not implemented and it does not have an abstract keyword then have the compiler do the work.”

    Here is that definition applied to an existing two different scenarios:

    1) public abstract string MyProperty { get; set; }
    This property is not implemented. Fine. It has an abstract keyword, so that’s cool.
    2) public string MyProperty { get; set; }
    This property is not implented. Fine. Wait a minute… no abstract keyword. I’ll create the property for you!

    So now apply this to a method.
    1) public abstract void MyMethod();
    This method is not implemented. Fine. It has an abstract keyword, so that’s cool.
    2) public void MyMethod();
    This method is not implemented. Fine. Wait a minute… no abstract keyword. I’ll create the method for you! Wait… umm…. how do I do that? … should I do that? What’s going on? INCONSISTENCIES!!! NOOOOO!!!! OMG!!! BOOOOM!

    Now on the other hand consider these two lines:
    public event MyEvent;
    public property string MyProperty;

    Both have similar syntaxes. Both have automatically-generated code. It’s a perfect succession.

    It only makes sense (to my VB.Net loving mind) that this be allowed to be explicitly defined as
    public property string MyProperty { get{} set {} }

    See the similarities(!!!!????):
    public property string MyProperty;
    public property string MyProperty { get{} set {} }

    public event MyProperty;
    public event MyProperty { add{} remove {} }

    Ahh… my brain relaxes at the overwhelming consistency of the above four lines. As Andrew said above, I’m completely against “continual cognitive dissonance”!

    ….
    After writing all this, I decided my point would become clearer if I blogged some very concrete syntax examples. They can be found here:
    http://joshmouch.wordpress.com/2007/02/16/syntax-consistency-among-class-members-events-properties-and-methods/

  11. Payton, and others: Why is it an issue what name is given to the autogenerated, not visible in code, field? The meaning, to me, is that you don’t use it. All access to it should go through the property, even inside the declaring class. That way you get full flexibility and no “lock-in” for the future.

  12. I like it, becasue it just cuts down on what you need to write to get the job done, without hurting anyone. And it’s pretty intuitive to understand.

    What I don’t like is that we have properties and also the readonly thing. Somehow I’d more like a unification of concepts.

    Come to think of it, in Eiffel, you can’t do this

    a . b = c

    unless

    a = this

    On the other hand, readonly is stricter yet, as it doesn’t even allow methods in the same class to alter it – except constructors.

    So if the new get-only pattern will generate a readonly variable, then that’d probably be a good thing, as it would automatically make the code more strict, I think.

    I think Anders H. himself dislikes the “many ways to Rome” – meaning the syntax should be as canonical as possible without making it oversimplistic.

    But you can question that with some of the syntax in C#.

    Some syntax can seem arbitrary. But I suppose that’s a characteristic of any ad-hoc language.

    I vastly prefer C#’s properties to Java’s reflection getX, setX, though. Even if it is a more canonical syntax (less is more). But less is more is only usable to a certain extent as not all of us enjoy brainfuck or assembler.

  13. I believe that automatic properties were added to the framework to support Linq…

  14. Automatic properties are next to useless because you can’t initialize them. The default values for strings and objects is null which is rarely what’s needed.

    I’ve gone back to always using the old way as I just ended up converting most of them anyway.

    Also it’s a pain they’ve removed the old snippet (although you can add it back in) so it now actually takes more time not less.

    If you’re going to provide syntactic sugar then it really should make life easier, not harder… Doh!

  15. Just in case anyone’s interested I’ve added a request for initialization of automatic properties to MS connect here:

    h ttp://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=361647

Comments are closed.