Wrapping a struct or class field in a property forces all accesses to that field to go through "getter" and "setter" methods. This allows for the possibility of adding logic for validation, lazy initialization, etc. Further, in the case of class fields, it allows for the possibility that one might have logic which applies to some instances but not others; if the properties are not virtual, it may be difficult to implement such logic efficiently (e.g. one would might have to define a static VerySpecialInstance
and have the property getter say if (this == VerySpecialInstance) GetSpecialProperty(); else GetOrdinaryProperty();
) but it could be done.
If, however, the semantics of a struct (e.g. System.Drawing.Point
) dictate that a particular read-write property may be written with any value which is legal for its type, writing will have no side effect other than to change its value, it will always return the last value written (if any), and if not written it will read as the default value for its type; and if code which uses the type will likely rely upon such assumptions, I'm unclear on what possible benefit would be served by using a read-write property rather than a field to hold the value.
The fact that Microsoft uses properties rather than fields for things like Point.X
etc. has historically caused confusion since MyList[3].X = 4;
would be translated to MyList[3].Set_X(4)
, and without looking inside the definition of Set_X
it's not possible to tell whether that method would achieve its desired effect without changing any fields of the struct in question; today's C# compiler will guess that it wouldn't work, and will forbid that construct even though there are some struct
types where property setters would in fact work just fine. If X
been a field rather than a property, and if Microsoft had said that the two safe ways to mutate a struct are either to access the fields directly or to pass the struct as a ref
parameter to a mutating method (which, if it's a static method of the struct type, could access public fields), such guesswork would not be necessary.
Given that using exposed struct fields rather than read-write properties improves both performance and semantic clarity, what reasons exist to make struct fields private and wrap them in properties? Data binding requires properties, but I don't think it works with structure types anyway (if one makes a copy of a struct and then sets some property of the original to one value and the corresponding property of the duplicate to another, what value should be reported to the bound object?) Are there some benefits of struct properties of which I'm unaware?
Personally, I think the 'ideal' struct in many cases would simply be a list of exposed public fields, and a constructor whose parameters are simply the initial values of those fields, in order. Such a struct would offer optimal performance and predictable semantics (behaving identically to all other such structs, aside from the types and names of the fields). Is there any reason to favor read-write properties in cases where there isn't anything they could do anything other than simply read and write an underlying field?