3 ms·
IMO Dart has the best implementation of properties, which you can start out as normal fields, e.g: class Rectangle { num left, top, width, height, ri
by mythz 12y ago
IMO Dart has the best implementation of properties, which you can start out as normal fields, e.g:
class Rectangle {
num left, top, width, height, right bottom;
}
and can access like normal:
var height = rect.bottom - rect.top;
But can later be changed into a computed property without affecting the above callsites, e.g:
class Rectangle {
num left, top, width, height;
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
C# is a close 2nd, but it's not binary (or reflection) compatible to change from a field to a property for call-sites (i.e. it's only source-compatible).
- mateuszf 12y agoafaik scalas properties are as good as in case of dart. Also, operations like + are also normal methods on numbers.
- srgpqt 12y agoRuby is quite similar. attr_accessor :left, :top, :width, :height, :right, :bottom And you can change these to computed properties (regular methods) later without affecting the callsites
- tieTYT 12y agoWhy does it matter if it's binary compatible? How does that affect the programmer? I guess I don't understand the difference/significance between binary and source compatibility? I'm surprised to hear that it's not reflection compatible. As a Java programmer, I assumed that was the main point of C# properties: Create a property now because there's no logic needed, but if you need logic in the future you can change the code and nobody outside needs to be aware of the change.
- mythz 12y agoBinary compatibility is important when accessing properties of a type defined in another Assembly, i.e. if an Assembly was updated where a Field was changed to a Property it would break access from dependent Assemblies. In .NET Reflection, Fields and Properties have distinct API's, i.e. fields can be accessed with `type.GetFields()` and properties with `type.GetProperties()`. The API's are basically wrappers around how they work, i.e. Fields let you get/set an instance's field value whereas with Properties you're instead invoking the properties getter/setter method accessors.
- dragonwriter 12y ago> As a Java programmer, I assumed that was the main point of C# properties: Create a property now because there's no logic needed, but if you need logic in the future you can change the code and nobody outside needs to be aware of the change. That's the point, but its not directed at reflection, and reflection goes around behind the scenes of the superficial access-notation compatibility. Which does make properties a badly leaky abstraction, which is problematic since their main reason for existing is to plug a leak in the abstraction provided by the method/field distinction.
- depoll 12y agoAnother important aspect of properties in C# is that they are a target for metadata (i.e. Attributes). This is something that's frustratingly broken with the method getter/setter approach. And while you can fix it by convention (e.g. a priority list for lookup on the getter, then setter, if those exist), it ends up being inconsistent and unnecessarily painful. Consistency of access in Java is also really problematic for the same reason. Which pair of getter/setter methods represents a reified property? This is often done by naming convention, that's usually, but not always consistent (getFoo/setFoo is common, but there's also isFoo/setFoo, isFoo/setIsFoo, foo()/foo(value), etc.). Worse (and this is something both Android's flavor of Java SDK and Objective-C have fallen prey to), not all properties are written symmetrically (e.g. getText() and the various setText() methods on an EditText in Android, although there are some where all of the setters are subclasses of the only getter -- even worse).
- ppog 12y agoYour comment about changing a field to a property being a breaking change in C# is correct, but in practice, C# programmers tend to use auto properties (e.g. public int Left { get; private set; }) rather than public fields. These are fully fledged properties, but the getters and setters are implemented by the compiler (and back directly onto a compiler-generated field). Because they are properties, they can then be changed to computed properties (or e.g. validation added to setters) without breaking binary or reflection compatibility.
- roller 12y agoIn C#, these aren't 100% source-compatible either. For example, you can't pass properties using ref or out parameters.
- zmmmmm 12y agoAmusingly, your Dart solution is exactly what Groovy does, which is where this whole thread started.