Propertys statt Getter und Setter Methoden?
-
SolidOffline schrieb:
Aber ihr habt schon recht: so ganz wörtlich sollte man die Empfehlung dann doch nicht nehmen.
Die Empfehlung ist schon okay, sofern die Beispiele in der MSDN auch in Ordnung sind (Weil gerade in WPF ist es nicht unüblich das dort noch Aufrufe für die Observer enthalten sind; Zudem behaupte ich mal das Bereichsprüfungen auch in mindestens einem Beispiel enthalten sind, ohne hierfür konkret nachzuschauen).
cu André
-
asc schrieb:
Es ist eben kein Sprachmerkmal - zumindestens keines des Sprachstandards.
So what? Dafür ist es eines in Delphi, C#, C++Builder etc. pp. Mein Punkt war, daß es kein Vorzug der IDE, sondern ein intrinsische Eigenschaft der Sprache ist.
asc schrieb:
Du bist imho der erste in diesen Thread der die Auffassung hat das Properties mehr als Getter und Setter sind.
Das ist natürlich auch ein Argument.
asc schrieb:
Attribute in C# können Sprachbestandteile ergänzen ohne Inhaltlich etwas zu ändern.
...Ja, was Attribute sind, weiß ich
asc schrieb:
Wir müssen aber nicht so sehr auf den Begrifflichkeiten rumhacken: Für mich ist eine Property halt Getter und Setter, für dich hat sie zudem noch weitere (Frameworkspezifische) Bedeutungen. Dies Ändert nichts an der grundlegenden Idee dahinter.
Ist es nicht "die grundlegende Idee dahinter", die wir da diskutieren, also die Motivation, überhaupt so etwas wie Properties in eine Sprache einzuführen?
Jedenfalls wäre ich interessiert, wie du ohne Properties ein Objekt serialisieren und über so etwas wie einen Objektinspektor modifizierbar machen willst. Wenn du da nur Getter und Setter benutzt, mußt du z.B. mindestens eine Konvention für deren Benennung erzwingen, so daß z.B. für ein Pseudoproperty "Height" Getter und Setter getHeight und setHeight heißen müßten; das resultiert in einer Inkonsistenz zwischen der Verwendung im Code und der Anzeige des Objektinspektors. Das ist mindestens unschön. Und wie wolltest du die Pseudoproperties mit Attributen versehen, z.B. (analog zu Delphi) default/nodefault, stored, index, oder was .NET so zu bieten hat?
-
audacia schrieb:
Jedenfalls wäre ich interessiert, wie du ohne Properties ein Objekt serialisieren und über so etwas wie einen Objektinspektor modifizierbar machen willst. Wenn du da nur Getter und Setter benutzt, mußt du z.B. mindestens eine Konvention für deren Benennung erzwingen
Ja. Und was spricht dagegen? Machen Java Beans doch auch. Man könnte auch, wie von Dir vorgeschlagen, Annotationen/Attribute verwenden. Alles kein Ding. Solange das Serialisierungs- bzw. Introspektionsframework diese Konvention kennt, ist alles machbar. Und das muss ja nicht zwingend Bestandteil der Sprache sein sondern kann eine freie Bibliothek oder gar ein vollkommen separates Tool (wie Google das mit den Protocol Buffers tut) sein.
-
Konrad Rudolph schrieb:
Machen Java Beans doch auch.
IMHO schon ein Argument dagegen. SCNR
Konrad Rudolph schrieb:
Man könnte auch, wie von Dir vorgeschlagen, Annotationen/Attribute verwenden. Alles kein Ding.
Wer bekommt die Attribute? Getter, Setter, beide? Falls letzteres, wie wird mit Redundanz und mit widersprüchlichen Attributen umgegangen? Falls nur einer, welcher?
-
audacia schrieb:
Konrad Rudolph schrieb:
Machen Java Beans doch auch.
IMHO schon ein Argument dagegen. SCNR
Hehe. Mag sein. Ich bevorzuge ja auch Properties.
Konrad Rudolph schrieb:
Man könnte auch, wie von Dir vorgeschlagen, Annotationen/Attribute verwenden. Alles kein Ding.
Wer bekommt die Attribute? Getter, Setter, beide? Falls letzteres, wie wird mit Redundanz und mit widersprüchlichen Attributen umgegangen? Falls nur einer, welcher?
Das sind natürlich alles gute Einwände. Wer ein entsprechendes Framwework bastelt, muss sich das gut überlegen. Ich habe keine pauschale Antwort darauf. Ich würde allerdings mal sagen, wenn man Annotations verwendet, dann müssen beide Methoden sowas erhalten (schon deswegen, weil man sonst gleich Namenskonventionen verwenden könnte, und auch, um Properties selektiv read-only zu machen). Man könnte sogar noch einen Schritt weitergehen und ganz andere Konventionen finden, z.B. (in Java) anonyme, verschachtelte Klassen, die von einem „Property“-Interface hergeleitet sind:
interface ReadOnlyProperty<T> { public T get(); } interface Property<T> extends ReadOnlyProperty<T> { public void set(T value); } class Foo { private int _x; public final Property<Integer> X = new Property<Integer>() { public Integer get() { return _x; } void set(Integer value) { _x = value; } }; } Foo f = new Foo(); f.X.set(42); System.out.println(f.X.get());
Ungetestet, so in der Art sollte das aber gehen und ich bin sicher nicht der erste, der auf diesen Trichter kommt.
/EDIT: getestet, korrigiert, klappt. Hui. Das lasse ich mir patentieren.
-
Und in C++ kann man Properties gut mit Template-Klassen nachbauen:
// property.h #ifndef PROPERTY_H #define PROPERTY_H template<typename T> class property_wrapper { public: explicit property_wrapper(const T& t) : _t(t) {} operator T() const { return _t; } private: const T& _t; }; template<typename T> class property_readonly { public: property_readonly() {} property_readonly(const T& t) : _t(t) {} const T& get() const { return _t; } const T& operator () () const { return _t; } operator T() const { return _t; } T& operator = (const property_wrapper<T>& t) { return _t = t; } protected: void set(const T& t) { _t = t; } const T& operator = (const T& t) { _t = t; return t; } const T& operator ()(const T& t) { _t = t; return t; } const T& operator += (const T& t) { _t += t; return _t; } const T& operator -= (const T& t) { _t -= t; return _t; } private: T _t; }; template<typename T> class property { public: property() {} property(const T& t) : _t(t) {} const T& get() const { return _t; } void set(const T& t) { _t = t; } const T& operator = (const T& t) { _t = t; return t; } const T& operator += (const T& t) { _t += t; return _t; } const T& operator -= (const T& t) { _t -= t; return _t; } const T& operator () () const { return _t; } const T& operator () (const T& t) { _t = t; return t; } operator T() const { return _t; } private: T _t; }; #endif
Und die Benutzung dann z.B. so:
void TestProperty() { class PropTest { public: PropTest() : x(0), y(0) {} void set_y(int value) { y = property_wrapper<int>(value); // only set property with wrapper class } property<int> x; property_readonly<int> y; }; PropTest p; p.x.set(0); //p.y.set(1); int x = p.x.get(); int y = p.y.get(); p.x(42); x = p.x(); p.x = 14; x = p.x; p.x = x; //p.y = 13; // no access to protected member //p.y(7); // same error -> OK p.set_y(7); y = p.y; p.set_y(y); }
Ich habe auch noch eine Variante, bei der man die Getter- und Setter-Methode explizit angeben kann...
-
Konrad Rudolph schrieb:
Das sind natürlich alles gute Einwände. Wer ein entsprechendes Framwework bastelt, muss sich das gut überlegen. Ich habe keine pauschale Antwort darauf. Ich würde allerdings mal sagen, wenn man Annotations verwendet, dann müssen beide Methoden sowas erhalten (schon deswegen, weil man sonst gleich Namenskonventionen verwenden könnte, und auch, um Properties selektiv read-only zu machen).
Das ist alles schön und gut, führt uns aber nur wieder zurück zu meinem Punkt: der Motivation, so etwas wie Properties in eine Sprache einzuführen. Neben dem Vorteil in der Lesbarkeit, den du ja zu Recht hervorhebst, hat man mit dem Sprachmittel der Properties eine eindeutige, leicht verständliche, redundanzfreie, nicht konventionsbindende Syntax, mittels derer man den Status eines Objektes repräsentieren kann; dies ist meines Wissens der Anlaß für die Einführung von Properties in Delphi gewesen. Daß es etwas schöner aussieht als Getter und Setter, ist ein legitimes Argument für Ästheten (und Sprachdesigner sollten einen Sinn für so etwas haben!), aber es ist nicht das Wesentliche.
-
ich hab jetzt nicht alles gelesen - aber
wieso behaupten so viele das propertys die kapselung zerstoeren
man muss ja nichtpublic int X { get; set; }
machen; da stimm ich zu, das ist keine kapselung mehr
dann macht man eben sopublic int X { get; private set; }
und feddich, schon issses readonly
oder mal direkt im vergleich
"herkoemmlich"class Bla { private int _x = 0; public int GetX() { return _x; } public void SetX(int x) { _x = x; } } //using int x = bla.GetX(); bla.SetX(x);
als property
class Bla { private int _x = 0; public int X { get { return _x; } set { _x = value; } } } //using int x = bla.X; bla.X = x;
hat man die selbe kapselung und ist im kontex dann deutlich lesbarer
//edit, class kleingeschrieben, ich mach zZt zu viel vbs #gg
-
Mr Evil schrieb:
wieso behaupten so viele das propertys die kapselung zerstoeren
Wer behauptet das?
-
Hah, großartig, audacia!
-
das war algemein gesprochen, nicht auf diesen thread bezogen
ich les das oefter
-
audacia schrieb:
Mr Evil schrieb:
wieso behaupten so viele das propertys die kapselung zerstoeren
Wer behauptet das?
Weiss nicht.
Dumme Leute?