Can someone tell me why the commented line of code (one before last) does not compile? Isn’t it the same as the line following it?
public struct OtherStruct
{
public int PublicProperty { get; set; }
public int PublicField;
public OtherStruct(int propertyValue, int fieldValue)
: this()
{
PublicProperty = propertyValue;
PublicField = fieldValue;
}
public int GetProperty()
{
return PublicProperty;
}
public void SetProperty(int value)
{
PublicProperty = value;
}
}
public struct SomeStruct
{
public OtherStruct OtherStruct { get; set; }
}
class Program
{
static void Main(string[] args)
{
SomeStruct a = new SomeStruct();
//a.OtherStruct.PublicProperty++;
a.OtherStruct.SetProperty(a.OtherStruct.GetProperty() + 1);
}
}
SomeStruct.OtherStructis a property, returning a value – it’s not a variable. This line:is like calling:
Because the expression
a.get_OtherStruct()is a value rather than a variable, it’s a bit like doing this:Changing the value of
PublicPropertyin the copy ofOtherStructreturned by the property isn’t going to change the original value at all. That’s almost certainly not your intention. The C# designers foresaw this sort of problem, and managed to prohibit it in many situations.Note that if
OtherStructwere a reference type (a class) instead, then it would be the reference that was copied, not the values within it… so changingtmp.PublicPropertywould make a difference. See my article on reference and value types for more information.Btw, mutable structs like this are generally a really bad idea. They cause all kinds of problems, and hard-to-predict code.
EDIT: In response to your “answer”, the two lines aren’t the same: the
a.OtherStructproperty expression isn’t the target of an assignment operator or a compound assignment operator.You can argue that you’d like C# to be defined in a way which would allow this (although I’d still disagree) but the compiler is implementing the specification correctly. See section 10.7.2 of the C# 3.0 spec for more details.