Allow out and ref for Properties and Indexers

Topics: C# Language Design
May 12, 2014 at 8:29 PM
Properties (as well as indexers) are a combination of get and set methods restricted in such a way that it can be coded as if it were a field. Most properties of a field also apply to a property, such as assigning, retrieving, and having the assignment operator return the value assigned. One place where the parity between properties and fields break down is with the use of out and ref parameters to a method call. When attempting, a compiler error results, stating "A property, indexer or dynamic member access may not be passed as an out or ref parameter." However, given that a property can optionally define a get method and a set method, out and ref can be supported.

Already, ref and out require that they be applied to an assignable variable, thus they should be able to be extended to requiring a property with the set method defined. An in parameter (one which is undecorated) would only require that a property has a get method defined (already required for the property to be part of an expression), an out parameter would only require that a property have a set method, and a ref would require the property to have both a get and set method. Any invalid combinations (e.g. out with a get only), would result in a compile error.

In the case of properties assigned to ref parameters, the get method of the properties would be called, then the values would be passed to the method. Once the method has returned, the final value of the ref parameters would be assigned to the corresponding properties.
In the case of properties assigned to out parameters, the method would be called without calling the get method of the properties, but, once the method returns, any value assigned to the out parameters would then be assigned to the properties.
May 13, 2014 at 12:48 AM
I would not consider this safe as a default behavior, but I would like to see attributes via which properties and ref/out parameters could specify when such a substitution should generally be considered safe, or should be explicitly regarded as unsafe. If either side of the connection views the transform as "unsafe", it should be forbidden. Otherwise, if either side regards it as "generally safe" it should be permitted.

Note that the rule should be applicable to the ref this passed to structure members; methods like the Offset of Drawing.Point which modify this should be tagged so as to indicate that should only be usable on properties if they're tagged as being safe for a read/modify/write cycle.