Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# property and ref parameter, why no sugar?

I just ran across this error message while working in C#

A property or indexer may not be passed as an out or ref parameter

I known what caused this and did the quick solution of creating a local variable of the correct type, calling the function with it as the out/ref parameter and then assigning it back to the property:

RefFn(ref obj.prop);

turns into

{
    var t = obj.prop;
    RefFn(ref t);
    obj.prop = t;
}

Clearly this would fail if the property doesn't support get and set in the current context.

Why doesn't C# just do that for me?


The only cases where I can think of where this might cause problems are:

  • threading
  • exceptions

For threading that transformation affects when the writes happen (after the function call vs. in the function call), but I rather suspect any code that counts on that would get little sympathy when it breaks.

For exceptions, the concern would be; what happens if the function assigns to one of several ref parameters than throws? Any trivial solution would result in all or none of the parameters being assigned to when some should be and some should not be. Again I don't think this would be supported use of the language.


Note: I understand the mechanics of why this error messages is generated. What I'm looking for is the rationale for why C# doesn't automatically implement the trivial workaround.

like image 613
BCS Avatar asked Feb 09 '09 20:02

BCS


3 Answers

Because you're passing the result of the indexer, which is really the result of a method call. There's no guarantee that the indexer property also has a setter, and passing it by ref would lead to a false security on the developer's part when he thinks that his property is going to be set without the setter being called.

On a more technical level, ref and out pass the memory address of the object passed into them, and to set a property, you have to call the setter, so there's no guarantee that the property would actually be changed especially when the property type is immutable. ref and out don't just set the value upon return of the method, they pass the actual memory reference to the object itself.

like image 108
David Morton Avatar answered Oct 14 '22 16:10

David Morton


Properties are nothing more than syntactic sugar over the Java style getX/setX methods. It doesn't make much sense for 'ref' on a method. In your instance it would make sense because your properties are merely stubbing out fields. Properties don't have to just be stubs, hence the framework cannot allow 'ref' on Properties.

EDIT: Well, the simple answer is that the mere fact that a Property getter or setter could include far more than just a field read/write makes it undesirable, not to mention possibly unexpected, to allow the sort of sugar you are proposing. This isn't to say I haven't been in need of this functionality before, just that I understand why they wouldn't want to provide it.

like image 21
user7116 Avatar answered Oct 14 '22 18:10

user7116


Just for info, C# 4.0 will have something like this sugar, but only when calling interop methods - partly due to the sheer propensity of ref in this scenario. I haven't tested it much (in the CTP); we'll have to see how it pans out...

like image 12
Marc Gravell Avatar answered Oct 14 '22 18:10

Marc Gravell