Property Declarations


What s Different in the Revised
Language Definition?

Declaring Properties



In the original language design, each set or get property accessor is
specified as an independent member function. The declaration of each method is prefixed
with the
__property keyword.
The method name begins with either
set_ or get_ followed
by the actual name of the property (as visible to the user). Thus, a Vector providing
an x coordinate get property would name
it
get_x and
the user would invoke it as
x.
This naming convention and separate specification of methods actually reflects the
underlying runtime implementation of the property. For example, here is a Vector with
a set of coordinate properties:

public __gc __sealed class Vector

{

public:

      //
&


 

      __property double get_x(){ return m_x;
}

      __property double get_y(){ return m_y;
}

      __property double get_z(){ return m_z;
}


 

      __property void set_x( double newx ){ m_x = newx;
}

      __property void set_y( double newy ){ m_y = newy;
}

      __property void set_z( double newz ){ m_z = newz;
}

};

This was found to be confusing because it spreads
out the functionality associated with a property and requires the user to lexically
unify the associated sets and gets. Moreover, it is lexically verbose as well and
feels inelegant. In the revised language design, which is more like that of C#, the
property keyword
(without the underscores) is followed by the type of the property and its unadorned
name. The set and get access
methods are placed within curly braces following the property name. Note that unlike
C#, the signature of the access method is specified. For example, here Vector properties
translated into the new language design well, no reason to duplicate all three coordinates.

public ref class Vector
sealed

{

public:

      property double x

      {

            double get()

            {

                  return m_x;

            }


 

            void set( double newx )

            {

                  m_x = newx;

            }


 

      }
// Note: no semi-colon &


 

      //
etc.


 

};

If the access methods of the property reflect distinct
access levels for example, a public get and
a private or protected set accessor
an explicit access label can be specified. By default, the access level of the property
reflects that of the enclosing access section. For example, in the above definition
of Vector, both the get and set methods
are public. To make the set method private,
the definition could be revised as follows:

public ref class Vector
sealed

{

public:

      property double x

      {

            double get()

            {

                  return m_x;

            }


 

      private:

            void set( double newx )

            {

                  m_x = newx;

            }


 

      } //
note: extent of private culminates here &


 

      //
note: dot is a public method of Vector &

      double dot( const Vector^ wv );



//
etc.



};

The extent of an access keyword within a property
extends until either the closing brace of the property or the specification of an
additional access keyword. It does not extend beyond the definition of the property
to the enclosing access level within which the property is defined. In the above declaration,
for example,
Vector::dot() is
a public member function.

Writing the set/get properties for the three Vector
coordinates is a bit tedious given the canned nature of the implementation: (a) declare
a private state member of the appropriate type, (b) return it when the user wishes
to get its value, and (c) set it to whatever new value the user wishes to assign.
In the revised language design, a shorthand property syntax is available which automates
this usage pattern:


 

public ref class Vector
sealed

{

public:

      //
equivalent shorthand property syntax

      property double x;

property double y;

property double z;

};


 

The interesting side-effect of the shorthand property
syntax is that while the backstage state member is automagically generated by the
compiler, it is not accessible within the class except through the set/get accessors.
Talk about the strict enforcement of data hiding!

disclaimer:
This posting is provided “AS IS” with no warranties, and confers no rights. 
    

 


Comments (7)

  1. AlisdairM says:

    "In the revised language design, a shorthand property syntax is available which automates this usage pattern:

    public ref class Vector sealed
    {
    public:
    // equivalent shorthand property syntax
    property double x;
    property double y;
    property double z;
    };"

    In principle I like this simplified syntax, but to aid my understanding I would like to check:

    Does the above example:

    i/
    Create private member variables m_x, m_y and m_z
    Create member functions get/set member functions
    Create appropriate CLI metadata to expose all these as properties to be consumed for other CLI tools.

    or

    ii/
    Create public data members called x, y and z
    Add appropiate CLI metadata to publish x,y and z as properties to be consumed for other CLI tools.

    iii/ Something different, but it really doesn’t matter how it works as the documented effect is the same and relying on hidden details is relying on an undocumented implementation that may change in a future version (if we find the need)

  2. stan lippman says:

    I don’t know that the implementation is fixed, apart from the visible semantics which are:
    a. the shadow state member is not visible to the user — it will be encoded such that you cannot access it
    b. a public get/set pair of methods are generated — there is no ability to specify alternative access levels or specify only one.
    c. i would presume that the metadata is available as you declare in (i), since otherwise it would be somewhat fractured, but i cannot directly confirm that.

    thanks.

    ps: i appologize for being tardy in answering the comments (that require an answer), but i honestly didn’t realize people were reading this … i know, naivity is not a viable excuse

  3. asdf says:

    Why do you have the T here:

    property T foo

    {

    }

    When the type is determined by the return value of the getter and the first parameter of the setter?

  4. stan lippman says:

    we felt it made things easier for the reader of the declaration. i thought folks would complain rather in having to specify T in the return type and parameter of the get and set accessors. so your point is well taken, asdf,

    but we choose to do what we felt was a more readable if explicit syntax.

  5. asdf says:

    property int x

    {

    double get() { return 1.0; }

    void set(const char *) { }

    }

    What if you have the above though? I take it this code is considered legal like the __declspec property extension already in VS would? In which case the type of x is redundant (and incorrect in this case).

  6. stan lippman says:

    no, the language does not allow you to do this. here is the clause from the latest draft of the ECMA standard [ongoing] — although the ability to overload set accessors has been bounced around …

    [18.4.2/30]

    The get accessor function of a scalar property takes no parameters and its return type shall match exactly the

    type of the property, simple-type-specifier.

    [18.4.2/35]

    The set accessor function of a scalar property has one parameter that corresponds exactly to the type of the

    property, simple-type-specifier.