C# property and ref parameter, why no sugar?

孤人 提交于 2019-11-27 00:59:48

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...

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.

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.

You can use fields with ref/out, but not properties. The reason is that properties are really just a syntax short cut for special methods. The compiler actually translates get / set properties to corresponding get_X and set_X methods as the CLR has no immediate support for properties.

It wouldn't be thread-safe; if two threads simultaneously create their own copies of the property value and pass them to functions as ref parameters, only one of them ends up back in the property.

class Program
{
  static int PropertyX { get; set; }

  static void Main()
  {
    PropertyX = 0;

    // Sugared from: 
    // WaitCallback w = (o) => WaitAndIncrement(500, ref PropertyX);
    WaitCallback w = (o) => {
      int x1 = PropertyX;
      WaitAndIncrement(500, ref x1);
      PropertyX = x1;
    };
    // end sugar

    ThreadPool.QueueUserWorkItem(w);

    // Sugared from: 
    // WaitAndIncrement(1000, ref PropertyX);
    int x2 = PropertyX;      
    WaitAndIncrement(1000, ref x2);
    PropertyX = x2;
    // end sugar

    Console.WriteLine(PropertyX);
  }

  static void WaitAndIncrement(int wait, ref int i)
  {
    Thread.Sleep(wait);
    i++;
  }
}

PropertyX ends up as 1, whereas a field or local variable would be 2.

That code sample also highlights the difficulties introduced by things like anonymous methods when asking the compiler to do sugary stuff.

The reason for this is that C# does not support "parameterful" properties that accept parameters passed by reference. It is interesting to note that the CLR does support this functionalty but C# does not.

Igor Zelaya

When you pass ref/out prepended it means that you are passing a reference type which is stored in the heap.

Properties are wrapper methods, not variables.

If you're asking why the compiler doesn't substitute the field returned by the property's getter, it's because the getter can return a const or readonly or literal or something else that shouldn't be re-initialized or overwritten.

This site appears to have a work around for you. I have not tested it though, so I can't guarantee it will work. The example appears to use reflection in order to gain access to the get and set functions of the property. This is probably not a recommended approach, but it might accomplish what you're asking for.

http://www.codeproject.com/KB/cs/Passing_Properties_byref.aspx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!