8

I've just found out (by discovering a bug) that you can do this:

string s = "3";
int i;
int.TryParse(s = "hello", out i); //returns false

Is there a legitimate use of using the returned value of an assignment?

(Obviously i++ is, but is this the same?)

dav_i
  • 27,509
  • 17
  • 104
  • 136
  • 3
    I'm not quite sure how this is a bug. – Arran Sep 24 '13 at 10:15
  • 3
    See Eric Lippert's answer here http://stackoverflow.com/a/3807583/187697 – keyboardP Sep 24 '13 at 10:25
  • 2
    @Arran The bug was that somebody had copied and pasted the signature of a method with an optional parameter and forgot to get rid of the default, causing undesired behaviour. No bugs in the code quoted here. – dav_i Sep 24 '13 at 10:26

5 Answers5

7

Generally I'd avoid using the return value of an assignment as it can all too easily lead to had to spot bugs. However, there is one excellent use for the feature as hopefully illustrated below, lazy initialization:

class SomeClass
{
    private string _value;

    public string Value { get { return _value ?? (_value = "hello"); } }
}

As of C# 6, this can be expressed using the => notation:

class SomeClass
{
    private string _value;

    public string Value => _value ?? (_value = "hello");
}

By using the ?? notation and the return value from the assignment, terse, yet readable, syntax can be used to only initialize the field and return it via a property when that property is called. In the above example, this isn't so useful, but within eg facades that need to be unit tested, only initializing those parts under test can greatly simplify the code.

David Arno
  • 42,717
  • 16
  • 86
  • 131
  • 1
    Interesting example. Are you missing `return` though? – dav_i Sep 24 '13 at 10:29
  • 1
    +1 for the great idea. need a pair of parenthesis to compile. public string Value { get { return _value ?? (_value = "hello"); } } – Menol Oct 14 '16 at 08:32
  • 1
    @Menol, thanks for spotting that.I've also updated it to mention the optional syntax that can be used with C# 6. – David Arno Oct 14 '16 at 08:42
5

This is legitimate.

s = "hello", is an expression which is evaluated / executed first, and the int.TryParse expression is executed after that.

Therefore, int.TryParse will use the content of 's' which is at that time "hello" and it's returning false.

nrsharma
  • 2,532
  • 3
  • 20
  • 36
Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
4

An assignment is an expression just like any other. This is valid syntax.

For the same reason this is valid:

int i;
int j;
int k;

i = j = k = 42;
heijp06
  • 11,558
  • 1
  • 40
  • 60
3

Is there a legitimate use of using the returned value of an assignment?

Yes.

From = Operator (C# Reference)

The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result.

That means = doesn't do assignment only, also it returns the value as an expression. Inside a method, your s reference now points to "hello" string not "3" anymore..

So,

int.TryParse(s = "hello", out i); 

is evaluated like;

int.TryParse("hello", out i); 

which since "hello" is not a valid integer, it returns false.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
1

You are basically asking:

Is it useful that assignment to a variable can be used as a value?

One place where it is useful is for daisy-chaining variable assignments:

string a, b, c;
a = b = c = "hello";

Which is clearer when parenthesized:

string a, b, c;
a = (b = (c = "hello"));

If c = "hello" did not have the value hello, then the above would not be possible. It has limited use elsewhere but has no real downside.

Paul Ruane
  • 37,459
  • 12
  • 63
  • 82