Reputation: 124
As I read before in some of this forums thread (here and here) properties are just syntactic sugar. This 2 implementations are the same after compilation:
class Item
{
string _name;
public string Name
{
get => _name;
set => _name = value;
}
}
class Item
{
string _name;
public string GetName() => _name;
public void SetName(string name) => _name = name;
}
If my hypothesis above it's true, why I can do this:
class Works
{
Item _item;
void SetItemName(string name) => _item?.SetName(name);
}
But I can't do this:
class Fails
{
Item _item;
void SetItemName(string name) => _item?.Name = name;
}
In the last example, _item?.Name = name
produces this compiler error:
The left-hand side of an assignment must be a variable, property or indexer
Upvotes: 1
Views: 103
Reputation: 1500225
Yes, properties are effectively syntactic sugar for methods with extra metadata, in terms of the generated code.
But that doesn't mean that the language rules for properties are always the same as for methods. The left-hand side of an assignment operator has to be a variable, property or indexer - but the expression _item?.Name
is classified as a value rather than a variable. The language could have been designed to allow this, without changing how properties themselves work at all, but this is what we've got at the moment. (It's possible that this could change in the future, too.)
In other words, this isn't about how properties are implemented internally, but about the C# rules that govern how they can be used - and in particular, how the assignment operator works. In fact, you can take properties out of the equation entirely - if you use a public field in Item
instead of a property, you'll see exactly the same error.
This isn't new to the null-safe dereferencing operator, either. Consider this example:
struct MutableStruct
{
public int Value { get; set; }
public void SetValue(int value) => Value = value;
}
class Test
{
static void Main()
{
Method().SetValue(10); // Valid, but not useful
Method().Value = 10; // Invalid
}
static MutableStruct Method() => new MutableStruct();
}
Here Method().Value = 10;
isn't valid because the Method()
expression evaluates to a value, not a variable (or a property or indexer).
Upvotes: 2