Why does C # not provide an internal helper for passing a property as a reference?

This is a question about LANGUAGE DESIGN.

Please do not answer the question until you read the whole post! Thanks.

With all the helpers existing in C # (like lambdas or automatic properties), it is very strange for me that I cannot pass a property by reference. Let's say I would like to do this:

foo(ref my_class.prop); 

I get an error, so instead I write:

 { var tmp = my_class.prop; foo(tmp); my_class.prop = tmp; } 

And now it works. But please pay attention to two things:

  • this is a general template, I didn’t add a type anywhere, only “var”, so it applies to all types and the number of properties that I need to pass

  • I need to do it again and again, to no avail - this is mechanical work

The existing problem actually kills useful features like Swap. Swap usually has a length of 3 lines, but since it takes 2 links, the call takes 5 lines. Of course, this is nonsense, and I just write "swap" manually every time I would like to name it. But this shows that C # prevents multiple code, badly.

QUESTION

So - what could be bad if the compiler automatically creates temporary variables (as I do manually), call the function and assign values ​​to the properties? Is this some kind of danger in this? I don’t see this, so I wonder how you think why the design of this problem looks the way it looks now.

Greetings

EDIT . Since the 280Z28 gave great examples for beating the idea of ​​automatically wrapping property references, I still find it useful to use packaging properties with temporary variables. Maybe something like this:

 Swap(inout my_class.prop1,inout my_class.prop2); 

Otherwise, there is no real Swap for C #: - (

+7
design c #
source share
8 answers

There are many assumptions about the meaning and behavior of the ref parameter. For example,

Case 1:

 int x; Interlocked.Increment(ref x); 

If you can pass a property by reference to this method, the call will be the same, but it will completely destroy the semantics of the method.

Case 2:

 void WaitForCompletion(ref bool trigger) { while (!trigger) Thread.Sleep(1000); } 

Summary: The by-ref parameter passes the address of the memory location to the function. An implementation that creates a temporary variable for "passing a property by reference" will be semantically equivalent to passing by value, which is exactly the behavior that you forbid when you make the parameter a ref one.

+8
source share

Your sentence is called copy-to-copy reference semantics. The semantics of copy semantics are no different from what we might call semantics "ref to variable"; different enough to be confusing and wrong in many situations. Others have already given you some examples; there are many more. For example:

 void M() { F(ref this.p); } void F(ref int x) { x = 123; B(); } void B() { Console.WriteLine(this.p); } 

If "this.p" is a property, with your suggestion it prints the old value of the property. If this field, it prints a new value.

Now imagine that you are reorganizing a field as a property. In real language, this causes errors if you followed a field through a ref link; The problem is brought to your attention. There is no mistake with your suggestion; instead, behavior changes quietly and subtly. This causes errors.

Consistency is important in C #, especially in those parts of the language that people find confusing, such as referential semantics. I would like any links to always be copy to copy or never copy to copy. Doing this one way sometimes and differently at other times seems like a very poor design for C #, a language that keeps the sequence concise.

+4
source share

Because the property is a method. This is a language construct that matches the pattern of encapsulating customization and searching for a private field using a set of methods. It is functionally equivalent to this:

 class Foo { private int _bar; public int GetBar( ) { return _bar; } public void SetBar( ) { _bar = value; } } 
+1
source share

With the ref argument, changes to the base variable will be observed by the method, this will not happen in your case. In other words, this is not exactly the same.

+1
source share
 var t = obj.prop; foo(ref t); obj.prop = t; 

Here the side effects of the getter and setter are visible only once, regardless of how many times the “by-ref” parameter has been assigned.

Imagine a dynamically calculated property. Its meaning may change at any time. With this construct, foo not updated , although the code suggests this ("I pass the property to the method")

+1
source share

So - what bad can happen if the compiler automatically creates temporary variables (as I do manually), call the function and assign the values ​​back to the properties? Is that any danger in him?

The danger is that the compiler does what you do not know. Creating code is confusing because properties are methods, not variables.

0
source share

I will give only one simple example where this can cause confusion. Suppose this is possible (as in VB):

 class Weird { public int Prop { get; set; } } static void Test(ref int x) { x = 42; throw new Exception(); } static void Main() { int v = 10; try { Test(ref v); } catch {} Console.WriteLine(v); // prints 42 var c = new Weird(); c.Prop = 10; try { Test(ref c.Prop); } catch {} Console.WriteLine(c.Prop); // prints 10!!! } 

Nice. Is not it?

0
source share

Because, as Eric Lippert likes to point out, every language function needs to be understood, designed, indicated, implemented, tested and documented. And this is clearly not a common scenario / pain.

-one
source share

All Articles