Properties Part 1 – the updated property syntax

What are properties?

Technically, properties are CLR “aliases.”  They are exposed as standard methods, and any compiler that consumes them simply transforms the user’s code into the proper function calls.  Similarly, any compiler that wants to author CLR properties just needs to follow the naming convention rules, and provide the necessary metadata entries.

The property appears as a red triangle in ildasm.  In the shot below, note that the functions implementing the property are not hidden or obfuscated.  Indeed, languages that don’t support the property can still call the underlying functions.

The Managed Extensions property syntax

__gc class MyClass{
  __property int get_MyProp(){ … }
  __property void set_MyProp(int value) { … }

int main(){
  MyClass* mc = new MyClass();
  return mc->get_MyProp();

By using the keyword __property, and providing a getter and/or a setter (using the naming convention get_PropName), a user was able to signal to the compiler that they wanted the extra property information generated.  When a user wanted to call a property, they would simply use the get_ and set_ functions directly.  This fit in the C++ syntax neatly, but it wasn’t exactly first-class.  Whereas other languages could get the length of an array by saying MyArray.Length, we were limited to MyArray->get_Length().

The new C++ property syntax

In the Whidbey syntax, the property is defined as a block, similar to how C# handles properties.  The general syntax uses the context-sensitive word property, followed by the general type of that property, followed by the name.  Curly-braces then define the “scope” of the property block, and inside, you’re allowed to define get and/or set functions that match the expected signature.  (The C# MSDN node on properties provides more context on how C# exposes properties.)

ref class MyClass{
  property int MyProp{
    int get(){ … }
    void set(int v){ … }

Calling properties is also similar to how C# handles them, with a few caveats.  In general, you should be able to call a property via its alias name, as in int i = myObject->MyProp, or myObject->MyProp = 10.  The compiler then transforms these calls into a getter or setter method, as appropriate.  This works on all properties, not just those you create.

More to come

In future articles, I’ll talk more about what you can do with properties, including:

  • default properties / default indexers
  • overloading of properties
  • limitations of properties in C++

Comments (4)

  1. Anonymous says:

    Hmm, I’ve always been able to call MyArray->Length instead of MyArray->get_Length(). I’ve never explicitely called a get_* or set_* function.

  2. Anonymous says:

    Oops. array->Length was a bad example. While it is true that, in some instances, you were allowed to simply call MyArray->Length, there are some properties (especially overloaded ones) where the only recourse in C++ is to call the property via the get_ and set_ methods.

  3. Anonymous says:

    Why do I have to specify the type of the property 3 times in the definition? It makes this new syntax more verbose than the old.

    Why not just adopt the C# style?

  4. Anonymous says:

    Disclaimer.  This is an ancient post.  By the looks of it, I originally intended to write this…