![]() |
Ist das ein D4 Bug ?
Delphi-Quellcode:
Diser Code geht.
private
p_Doc_Type : String; procedure Setze_Doc_Type(s:string); protected // Das OLE-Objekt, die Desktopinstanz und das Dokument selbst. Service, Desktop, Document : Variant; public property Doc_Type:String read p_Doc_Type write Setze_Doc_Type; Wenn ich jetzt dass hier einbauen will, denn die Übergabe ist unnötig
Delphi-Quellcode:
also den Parameter weg lasse dann motzt er bei der property über Incompatible Types :(
procedure Setze_Doc_Type;
|
Re: Ist das ein D4 Bug ?
Nur mal so: wie kommst du darauf, daß der parameter unnötig ist?
du hast ein write darin (@Daniel: welches im Gegensatz zu unserem Highlighter bei euch hier wohl nicht gehighlightet wird :-P), also wird zum setzen des Wertes die Prozedur "setze_doc_type" aufgerufen. Wie soll diese Prozedur jetzt wissen, auf welchen Wert es den setzen soll? Natürlich brauchst du den Parameter. Computer sind zwar unglaublich schnell im Rechnen, raten können sie aber trotzdem nicht :-P |
Re: Ist das ein D4 Bug ?
Der Setter-Methode für eine Porperty mußt Du IMHO immer einen Wert mitgeben. Das sollte bei allen Delphi-Versionen so sein.
|
Re: Ist das ein D4 Bug ?
Zitat:
|
hmm,
@tommie-lie
Das macht IMHO keinen Sinn, die Setze Methode sieht ca. so aus
Delphi-Quellcode:
Der üebrgebene Parameter wird also gar nicht gebraucht ! Ich rufs jetzt halt so auf
procedure Setze_Doc_Type(s:string);
var rueckgabe : String; begin rueckgabe := ''; if (Document = 'xyz') then rueckgabe := 'xy-Typ' else rueckgabe := 'unknown'; p_Doc_Type := rueckgabe; end;
Delphi-Quellcode:
sinnig ist dies aber nicht wirklich.
Setze_Doc_Type('Dummy');
|
Re: hmm,
Zitat:
Von einem Property verlange ich normalerweise, daß der Wert, den ich ihm übergebe, darin landet. Und dazu muss der Prozedur Set[Property] nunmal der Wert als Parameter übergeben werden. Ansonsten verlange ich eigentlich, daß mir der Compiler sagt, daß ich dem Ding nichts zuweisen kann. Und da du hier ein write für das Property angibst, geht der Compiler ganz richtig davon aus, daß es benutzt wird um den Wert des Porperties zu schreiben und will ihm natürlich den Parameter übergeben. Hat die prozedur diesen nicht, meckert er. Ich würde an deiner Stelle nochmal über Klassendesign nachdenken :roll: |
hmm,
Zitat:
|
Re: Ist das ein D4 Bug ?
Hi JoelH,
ich glaube, dein Problem steckt im Verständnis was hier abläuft. Wenn du schreibenderweise auf deine Property Doc_type zugreifst, dann hast du in der Objecterstellung natürlich zwei Möglichkeiten.
Delphi-Quellcode:
oder
private
p_Doc_Type : String; protected // Das OLE-Objekt, die Desktopinstanz und das Dokument selbst. Service, Desktop, Document : Variant; public property Doc_Type:String read p_Doc_Type write p_Doc_Type;
Delphi-Quellcode:
Nun machst du bei der Benutzung natürlich das gleiche bei beiden Varianten:
private
p_Doc_Type : String; procedure Setze_Doc_Type(s:string); protected // Das OLE-Objekt, die Desktopinstanz und das Dokument selbst. Service, Desktop, Document : Variant; public property Doc_Type:String read p_Doc_Type write Setze_Doc_Type;
Delphi-Quellcode:
Jetzt passiert im Rahmer der proceduralen Zuweisung nur folgendes. Du kannst in der Procedure Setze_Doc_Type mit dem Parameter s mehr machen als ihn nur dem Property p_Doc_Type zuweisen.
MeinObject.Doc_Type := 'nasowas';
Fälschlich ist die Annahme, dass du die Procedur Setze_Doc_Type über die Objectinstanz aufrufen kannst. Aus diesem Grund steht sie ja auch im private-Teil. Also, von außen allen gleich und von innen anders. Übrigens, von Dummyparameter kann keine rede sein, denn wenn du read deklarierst dann geht es um "Schreiben" und dazu gehört auch ein Parameter. Eben was geschrieben werden soll. Gruß oki |
Re: hmm,
Zitat:
Als Parameter wird immer der Wert übergeben, den ich dem Property zuweisen will, und das erwarte ich auh von einer Klasse. Das erwartet jeder Programmierer, ob das nun ObjectPascal, C++ oder sonstwas ist! Wie bereits gesagt, mach dich mal über Klassendesign schlau, dann verstehst du, daß deine Deklaration da oben auf gut deutsch gesagt besch...eiden ist. Sorry für die Ausdrucksweise, aber ich hab' keinen Bock, daß das wieder so eine Diskussion wird wie die mit Stephan über Open- und ClosedSource. :roll: |
hmm,
@tommie-lie
Hast du ein Problem ? Ich hab ganz ordentlich gefragt, wenn dir das nicht passt dann antworte halt nimmer, hab ich kein Problem mit, oki's Betrag hat mir mehr geholfen als deine zusammen. @oki Jetzt wird es mir zwar klarer, verstanden hab ich den Sinn noch immer nicht. Der Compiler sollte wissen dass da eine procedure rennt und deshalb der Parameter entfallen kann weil er nicht unbedingt gebraucht wird !? Zitat:
|
Re: Ist das ein D4 Bug ?
Hi,
irgentwie ist es ja so, wenn du meine erste Variante verwendest.
Delphi-Quellcode:
Hier wird auch direkt zugewiesen.
public
property Doc_Type:String read p_Doc_Type write p_Doc_Type; Wenn du jetzt aber anstatt write p_Doc_Type eine Procedure verwenden kannst, dann muß das ja einen Sinn haben. Der Sinn ist dabei, dass du den zugewiesenen Wert weiterverarbeiten kannst. Mal ein praktisches Beispiel. Du benutzt irgentwo in deinem Object eine Variable die einen Zeitwert beinhaltet. Zum Beispiel für einen Timer. Nun erwartet der Timer einen Wert für millisekunden. Da jeder Otto-Normalverbraucher mit Sekunden besser klar kommt willst du ihm die Möglichkeit geben auch Sekunden einzugeben und dann, wenn ein Zugriff an Mehreren Stellen deines Programms erfolgt nicht jedes mal daran denken müssen vor der Zuweisung umzurechnen (also immer wieder im Hauptprogramm Wert*1000 zu schreiben). Hier macht die Procedure hinter write richtig Sinn. Bsp.:
Delphi-Quellcode:
Das gleiche funzt natürlich auch für read mit einer Funktion:
procedure Setze_Sekunden(Value : Longint);
begin P_Meine_Millisekunden := Value*1000; end;
Delphi-Quellcode:
Gut, ich hoffe, dass hat geholfen.
Function Lese_Sekunden: Longint;
begin Result := Trunc(P_Meine_Millisekunden/1000); end; Gruß oki |
hmm,
und dann fiel es ihm wie Schuppen von den Augen :D
Ich bin gerade über meine Klassenvariable ansich gestolpert :( danke oki :) |
Re: hmm,
Zitat:
Dem war nicht so, also gut: Ein Property dient dazu, Werte zu schreiben, und zwar öffentlich. Dazu bietet sich die Möglichkeit von Read- und Write-Deklarationen dazu an, auch Prozeduren, bzw Funktionen anzugeben, die zuvor den Wert aus einer Variable irgendwie behandeln. Eine Multiplikation/Division mit 1000 aus okis Beitrag wäre ein Beispiel dazu, denkbar wäre z.B. bei einem Timer das Interval-Property daß der Timer im System neu angemeldet wird, mit dem neuen Interval. Die read-Deklaration muss eine function sein, die write-Deklaration eine procedure. Der Rückgabewert der read-Funktion wird dabei als Wert des Properties abgetragen, wenn man irgendwo im Code sowas stehen hat wie [delphi]MyVar := MyClassInstance.MyProperty[Delphi] Dabei wird die read-Funktion aufgerufen (ohne Parameter, da unnötig) und der Wert dieses Ergebnisses in MyVar geschrieben. Ruft man stattdessen [delphi]MyClassInstance.MyProperty := MyVar[Delphi] auf, so wird natürlich die write-Prozedur aufgerufen um den Wert aus MyVar dem Property zuzuweisen. Wie soll jetzt diese Prozedur (wenn nicht direkt dem Feld der Klasse übergeben wird) wissen, welchen Wert es schreiben soll? Natürlich über den Parameter. DIES ist der eigentliche Sinn und Zweck des ganzen. Daher geht der Compiler, der der OOP mächtig ist, davon aus, daß der vor ihm sitzende Programmierer dies auch ist, und will der Prozedur den dem Property zugewiesenen Wert als Parameter übergeben, auf daß die Prozedur schon das richtige mit diesem Wert anstelle. Auf diese Weise verlange ich (als Benutzer deiner Klasse), daß ein Wert, den ich einem Property zuweise, in irgendeiner Art und Weise in der Klasse landet. Meinetwegen lasse ich mir noch gefallen, daß ich ihn nicht wieder auslesen kann, weil er irgendwie umgeformt wurde, aber ich will, wenn ich irgendwas mache, daß auf das, was ich gemacht habe, darauf reagiert wurde. Was du hingegen machst, du missbrauchst ein Property dazu etwas zu tun, was eigentlich in einer public-procedure wie "Initialize" hätte stehen sollen. Ein Property ist nicht dazu da, irgendwelche Werte irgedwie zu setzen, sondern die gewünschten Werte auf den von mir angegebenen Wert zu setzen. |
hmm,
ich benutze C/S, ich besitze es nicht. Vorurteile sind schlecht. Ich stolperte nicht über das Problem an sich sondern über die Syntax.
|
Re: hmm,
Zitat:
Es ist genau das Problem an sich, denn IMHO hast du den Sinn von Properties nicht ganz verstanden. Ob du das jetzt mittlerweile hast, weiß ich nicht, aber da oben war das auf jeden Fall nicht der Fall! |
hmm,
für mich ist eine Property etwas was von einer Klasse zur Verfügung gestellt wird. Die Farbe der Hose etc. Bei mir ist es der Typ des Dokuments, welche man kennen sollte aber nicht verändern darf, macht ja auch keinen Sinn. Also Property public aber die Variable Private und die Schreibmethode darauf auch. Natürlich war es ein Designfehler da eh nur die Klasse auf die Var zugreifen kann. Allerdings rechtfertigte dies, in meinen Augen nicht, warum ich was übergeben muss was ich, nachweisslich, nicht brauche. Auch wenn der Designfehler da ist gibt es keinen Grund einen inkompatiblen Typ zu melden da man , nachweislich, einfach einen Dummy übergeben kann.
|
Re: hmm,
Zitat:
Und wenn ich sage Hose.Farbe := rot, dann verlange ich, daß nachher in diesem Property "rot" drinsteht. [/quote]Bei mir ist es der Typ des Dokuments, welche man kennen sollte aber nicht verändern darf[/quote] Dafür sind read-only-Properties da, die haben keine write-Prozedur und denen darf man keinen Wert zuweisen. Zitat:
Zitat:
Der Fehler ist, daß du dem User erlaubst, etwas zu schreiben, ohne daß das, was er geschrieben hat, in irgendeiner Form berücksichtigt wird. Das ist der Fehler. Zitat:
Deine Prozedur:
Delphi-Quellcode:
ist eher eine read-Methode (evtl sogar als Fragment für die Funktion, zum Laden des Dokumentes (LoadFromFile?)), aber alles andere als etwas, um einen Wert in ein Property zu schreiben.
procedure Setze_Doc_Type(s:string);
var rueckgabe : String; begin rueckgabe := ''; if (Document = 'xyz') then rueckgabe := 'xy-Typ' else rueckgabe := 'unknown'; p_Doc_Type := rueckgabe; end; Zitat:
|
Re: hmm,
Zitat:
[/quote] Zitat:
[/quote] Irgendeiner muss doch reinschreiben, also die Klasse selbst via private Procedure. Ich hab doch schon gesagt ich hab mir da selbst ein Gespenst eingeredet. Zitat:
|
Re: hmm,
Zitat:
Zitat:
Und was zum Beschreiben braucht man auch nciht immer. Wie gesagt, ich weiß nicht, wie C eine Klasse deklariert, aber sicherlich wird es da etwas ähnliches geben wie die reads und writes von Delphi, und auch da kann man sicherlich das write oder das read weglassen. Wenn nicht, ist die Sprache ärmer als ich dachte (und das jetzt, wo ich auch mal C++ lernen wollte :-/ ). Zitat:
Zitat:
Du sollst per Definition keine globale Variable übergeben! Ich weiß nicht, was der Rest deiner Klasse macht, aber wenn du wirklich auf globale Variablen zugreifst, ist es absolute Vergewaltigung, ein Property dafür zu benutzen, vor allem, weil man auf globale Variablen sowieso von überall her zugreifen kann. Deine ganze Prozedur gehört nicht zu einem Property. Einer read-Methode für ein Proeprty übergibt man einen Wert, der irgendwo hingeschrieben wird (in die Klasse, bzw deren Instanz), es holt sich die Daten nicht aus irgendwelchen globalen Variablen! |
hmm,
'global' = Klassenvariable, darum die '' , denn die private Variable ist global in der Klasse verfügbar. Deshalb doch mein 'Verständnisproblem' mit dem beschreiben der Variable. Die muss , innerhalb der Klasse, nicht übergebenw erden. Sie sit private, warum will der Compiler also dass ich was übergebe ? Das ist mein einzigese Problem hier.
Es ist einfach in meinen Augen nicht transparent. Ich verstehe schon was du meinst, du meinst er muss ja was übergeben bekommen damit er die Property mit leben füllen kann. Das ist ja gar nicht die Frage, die Frage ist warum man einen Dummywert übergeben MUSS und ohne den Dummy einen Typefehler bekommt. Für mich ist dies einfach inkonsistent, denn wen schon dann muss man auch was richtiges übergeben müssen. Deshalb meine ich eben es inkonsequent. Ich hoffe du verstehst nun mein Problem. Es ist eher ein innerer Konflikt. Ich mag es nicht wenn der Compiler mich erst anmotzt aber dann einen Dummy schluckt. |
Re: hmm,
Zitat:
Sobald du schreibst
Delphi-Quellcode:
wird der String "Hello" an die prozedur "SetMyProperty" als Parameter übergeben. Vollkommen automatisch, da soll man gar keine Dummyparameter angeben.
MyInstance.MyProperty := 'Hello'
Der Typenfehler kommt, weil das property vom Typ String ist. Wenn du Setze_Doc_Type ohne Parameter deklarierst, ist "kein Parameter" natürlich nciht mehr kompatibel mit "String" ;-) Zitat:
Was das für genaue Ursachen hat, weiß ich immo auch nicht genau. Dazu müsste ich Delphi starten, was aber eine Option ist, die mir zur Zeit leider nicht zur Verfügung steht. Ich tippe aber einfahc mal darauf, daß man der Prozedur einen zweiten Hilfsparameter angeben kann, falls du zum Beispiel die gleiche Set-Methode für mehrere properties verwendest, damit die Methode weiß, welches Property es war (beispielsweise bei mehreren Hosenangaben, die alle die gleichen Farbwerte erhalten können :) ). Dadurch könnte der Compiler direkte Übergaben von Werten akzeptieren, aber wie gesagt, genaueres kann ich dir da immo nicht sagen. Wenn cih dran denke, werde ich nachher der Sache nachgehen. |
Re: Ist das ein D4 Bug ?
Hi Leute.
Ich glaube JoelH hat ein Verständnisproblem mit der Sichtbarkeit von Klassenelementen. Hier mal die Delphi-Hilfe zu diesem Thema. Vielleicht wird dann einiges klarer. In einer Klasse hat jedes Element ein Sichtbarkeitsattribut, das durch die reservierten Wörter private, protected, public, published und automated angegeben wird. Im folgenden Beispiel wird die Eigenschaft Color als published deklariert: published property Color: TColor read GetColor write SetColor; Die Sichtbarkeit bestimmt, wo und wie auf ein Element zugegriffen werden kann. private entspricht der geringsten, protected einer mittleren und public, published und automated der größten Sichtbarkeit. Der ganze Zauber mit Property und read /write ist nur dafür da, dann Klassenvariablen im "öffentlichen" Umgang für schreiben und lesen einzuschrängen oder in der Bearbeitung in der Klasse zugriffsfähig zu machen (siehe mein Beitrag weiter oben). Gruß oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz