-2

Possible Duplicate:
Why do assignment statements return a value?

In C# you can use a property as both an lrvalue and rvalue at the same time like this :

int n = N = 1;

Here is a complete C# sample :

class Test
{
    static int n;

    static int N
    {
        get { System.Console.WriteLine("get"); return n; }
        set { System.Console.WriteLine("set"); n = value; }
    }

    static void Main()
    {
        int n = N = 1;

        System.Console.WriteLine("{0}/{1}", n, N);
    }
}

You can't do that in C++/CLI as the resulting type of the assignment expression "N = 1" is void.

EDIT1: here is a C++/CLI sample that shows this :

ref class A
{
    public: static property int N;
};

int main()
{
    int n = A::N = 1;

    System::Console::WriteLine("{0}/{1}", n, A::N);
}

EDIT2: Moreover this is really confusing : what I was expecting was that the getter would be call to assign to n which is not the case at all; n directly receives the right-most value of the expression, i.e. 1 like shown by the generated CIL :

IL_0001:  ldc.i4.1
IL_0002:  dup
IL_0003:  call       void Test::set_N(int32)
IL_0008:  nop
IL_0009:  stloc.0

So what's the magic behind C# syntax allowing a void-expression to be used as a rvalue ?

Is this special treatment only available for properties or do you know other C# tricks like this ?

EDIT : As pointed out C# assignment rules say that rvalue should ALWAYS be used as the return value of an assignment.

Community
  • 1
  • 1
Pragmateek
  • 13,174
  • 9
  • 74
  • 108
  • a=b=c is valid c/c++ - value of an assignment is (usually)the value of the assigned variable. I am not sure about C++/CLI – Karthik T Nov 28 '12 at 10:16
  • @Karthik : I'm talking of "properties" which are special animals that do not exist in standard C++, they are a mix of fields and methods :) – Pragmateek Nov 28 '12 at 10:20
  • @musefan: the question you mention is essentially about non-preoperties objects. Please have a look at my comment to trippino answer about what is said by Eric Lippert. – Pragmateek Nov 28 '12 at 11:00
  • You are getting hung up over nothing. You should just accept that this is how it works in C#. What's being said is that `n` becomes the result of an assignment (`N = 1;`). It had nothing to do with what goes on in the setter, it's more about that the `N = 1` expression produces - which is the value `1`, and that is what gets assigned to `n` – musefan Nov 28 '12 at 11:13
  • Yes, but what I'am asking for is some rationales from experts; because though design decisions are often useless to know in the daily job of a profesionnal developper, this is always interesting for a geek :) especially when the behavior is different from the one of a language (C++/CLI) designed from the same platform but with different constraints, like C++ compatibility. – Pragmateek Nov 28 '12 at 11:18
  • @Serious Please be **serious** and stop adding many updates to your question that are repeating the same thing all over again. What part of "it's not about properties" don't you understand? **It's about ALL kind of assignments**. You're in the wrong way... Now it's up to you to understand this. – Matías Fidemraizer Nov 28 '12 at 11:24

3 Answers3

1

What magic, just try to look at it as two expressions.

N = 1;//sets N to 1
n = N;//sets n to the value of N, which is 1

What's not to understand?

musefan
  • 47,875
  • 21
  • 135
  • 185
  • "N=1" is syntactically speaking an "expression"; an expression has a return value : expression "N" has type "int" as the result of its evaluation is an integer. "N=1" has type "void" in C++/CLI and logically in C# too as it is the result of the evaluation of the setter of the property which always returns "void". So it seems like C# is handling n=N=1, which is equivalent to n=(N=1), in a special manner; that's precisely my question, hope it's clearer now, sorry for not having made it clear upfront :) – Pragmateek Nov 28 '12 at 10:27
  • this isn't C++, [maybe read this thread](http://stackoverflow.com/questions/3807192/why-do-assignment-statements-return-a-value) – musefan Nov 28 '12 at 10:33
  • Yes, but it is C++/CLI. I'll remove the C++ tag as it's adding more confusion that it brings help :) – Pragmateek Nov 28 '12 at 10:42
1

you have the answer here and here

Basically:

First off, assignment statements do not return a value. Assignment expressions return a value. An assignment expression is a legal statement; there are only a handful of expressions which are legal statements in C#: instance construction, increment, decrement, invocation and assignment expressions may be used where a statement is expected.

and

The result of a simple assignment expression is the value assigned to the left operand. The result has the same type as the left operand and is always classified as a value.

Community
  • 1
  • 1
Tobia Zambon
  • 7,479
  • 3
  • 37
  • 69
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Toon Krijthe Nov 28 '12 at 10:46
  • 1
    @GamecatisToonKrijthe you are right, sorry, I've edited the answer – Tobia Zambon Nov 28 '12 at 10:53
  • @trippino: the first link is essentially about non-properties objects; and as stated by Eric Lippert : "There is only one kind of expression in C# which does not produce some sort of value, namely, an invocation of something that is typed as returning void.", which is precisely the case for a property setter :) The second link does not seem to speak about the return value of the result of the expression "x=y", it's just about the way it is "invoked". – Pragmateek Nov 28 '12 at 10:54
1

In C#, an assignment is the result of the assignment itself.

For example:

string a = null;

if((a = "hello world").Contains("world"))
{
      Console.WriteLine("It has 'world' word!");
}

As you see, it's not about properties, but assignments.

An statement like this:

int n = N = 1;

...is equivalent to:

int n = (N = 1);

The point of this is (N = 1) has a return value itself: an integer value of 1.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • Yes, so this means special handling : overriding the true nature of setter which is to return void, like this is in C++/CLI, to return the result of the evaluation of the property itself. – Pragmateek Nov 28 '12 at 10:57
  • 1
    @Serious there's no "true nature". There're a plenty of them. I mean that a behavior of other languages like C++ isn't the "true nature of an assignment". There's no special magic or special handling, but C# way of handling assignments. An assignment is an expression, so why should it be void? – Matías Fidemraizer Nov 28 '12 at 11:18
  • 1
    @Serious Ah, and I believe you're not accurately reading my answer. It's not about *setters* or whatever. This is a rule for ANY assignment. And at the end of the day, the *setter* isn't the one returning a value of the expression, **it's the right part of the expression!!** – Matías Fidemraizer Nov 28 '12 at 11:20
  • Because C# properties are just syntaxic sugar over method invocation : N = 1 is from the point of view of the CLR : Test::set_N(null, 1) which returns void. – Pragmateek Nov 28 '12 at 11:22
  • Yes I've seen this too by looking at my output and CIL and have updated my question. It may be quite confusing, but rules are rules, and I know one more now :) – Pragmateek Nov 28 '12 at 11:24
  • @Serious You're in the wrong way, you can update, re-update and re-re-re-re-re-re-update your question, but you're thinking about properties. Don't you understand that for example `string a; string b; a = (b = GetText());` would be the exact thing? – Matías Fidemraizer Nov 28 '12 at 11:27
  • Yes but the question is why different behaviors in C# and C++/CLI. I know this is a tricky (and probably useless) one but I'd be glad to know. I've +1 your question as it pointed out the C# behavior of "use right-most value". Thanks. – Pragmateek Nov 28 '12 at 11:58
  • 1
    @Serious Thanks. Sometimes there's no anwer: C++ is A and C# is B. There's no explanation, but a design decision. – Matías Fidemraizer Nov 28 '12 at 14:14