![]() |
VAR oder nicht VAR Überlegungen
Hallo Zusammen.
Unit A definiert:
Delphi-Quellcode:
Unit B definiert:
type
TFoo = Record MeinFeld : String; end;
Delphi-Quellcode:
Dann gibt es noch Unit C mit
type
TFoo = Class Public MeinFeld : String end;
Delphi-Quellcode:
oder besser?
Procedure A(AFoo : TFoo);
begin AFoo.MeinFeld := 'Warum kommt das hier nicht zurück'; end;
Delphi-Quellcode:
OK, Worum geht es mir?
Procedure A(Var AFoo : TFoo);
begin AFoo.MeinFeld := 'Das kommt auf jeden Fall zurück'; end; Bei Records macht der Var Parameter einen Unterschied. - Call bei Referenz - Call bei Value Theoretisch bei Classen auch, aber nur für den Objectzeiger. Wenn ich also nach 5 Jahren mir eine Procedure anschaue kann ich mich ggf. nicht mehr daran erinnern, ob TFoo ein Object oder ein Record ist. Daher meine These oder nennt es mein DesignPattern. Wenn an Procedure ein Objekt übergeben wird, schreibe ich immer VAR. So kann ich an der Definition der Procedure sehen, dass wenn ich innerhalb der Procedure etwas mit AFoo mache, es Auswirkungen nach draußen hat. Bin gespannt auf Eure Kommentare. Besonders ob wenigsten einer Dabei ist mit "Gute Idee"... :stupid: Mavarik |
AW: VAR oder nicht VAR Überlegungen
Tendenziell eher schlecht als gut. Im Normalfall will man ja an der Objektinstanz an sich überhaupt nichts verändern, sondern lediglich mit deren Methoden oder Properties arbeiten, wieso also als Variablenparameter übergeben? Es kann natürlich auch Ausnahmen geben, aber das sind dann meist wirklich Ausnahmen. Wenn die Übergabeart schon dazu dienen soll, auseinanderzuhalten, was ein Record und was eine Klasse ist (wobei mir das schon überdenkenswert erscheint), dann übergib doch Objektinstanzen als Konstantenparameter, da kann dann auch nichts schiefgehen.
|
AW: VAR oder nicht VAR Überlegungen
Zeig doch bitte mal wie Unit A, Unit B und Unit C zusammengesteckt aussehen.
Denn entweder ist
Delphi-Quellcode:
in Unit C der
TFoo
Delphi-Quellcode:
oder die
Record
Delphi-Quellcode:
, aber es geht niemals das überraschenderweise mal die Klasse oder der Record in die Prozedur von Unit C läuft.
class
Das muss man also schon bewusst so programmieren.
Delphi-Quellcode:
Und auch wenn da beide gleich benannt sind, handelt es sich intern um grundverschiedene Typen, so als ob der eine Typ
unit C;
interface uses A, B; procedure A( var Foo : A.TFoo ); overload; // record procedure A( Foo : B.TFoo ); overload; // class
Delphi-Quellcode:
und der andere
TAnton
Delphi-Quellcode:
heißen würde.
TFritz
Das Grundverhalten von
Delphi-Quellcode:
und
record
Delphi-Quellcode:
ist nun mal auch grundverschieden, dass man die eben nicht über einen Kamm scheren kann.
class
|
AW: VAR oder nicht VAR Überlegungen
Find ich auch eher nicht so gut. Denn wenn ein Objekt als var übergeben wird, dann erlaubt das der aufgerufenen Routine, den Zeiger zu verändern. Also wenn, dann würde ich als „Design Pattern“ eher vorschlagen, Objekte, die verändert werden könn(t)en „normal“ zu übergeben (ohne var und const), und Objekte, die explizit nicht verändert werden dürfen als const (ja ich weiß, dass das const das nicht verhindert, aber zumindest macht es es nicht noch schlimmer im Gegensatz zum var).
Mache ich aber selber nicht so, ich hatte das Problem eigentlich nie. |
AW: VAR oder nicht VAR Überlegungen
Am Rande eine dumme Frage- Es macht doch für den Aufrufer keinen Unterschied ob ein Parameter const oder nicht const ist, oder?
|
AW: VAR oder nicht VAR Überlegungen
Man muss sich immer vor Augen halten, was denn da genau übergeben wird, und das ist bei einem Record und einer Klasse eben etwas völlig anderes.
Der Prozeduraufruf arbeitet bei beiden gleich: Bei
Delphi-Quellcode:
ist der Wert nicht änderbar, bei
const Value : Type
Delphi-Quellcode:
ist der Wert änderbar, geht aber nicht zurück und bei
Value : Type
Delphi-Quellcode:
ist der Wert änderbar und wird zurückgegeben.
var Value : Type
Aber bei einem Record ist der Wert eben der gesamte Inhalt des Records und bei einer Klasse ist der Wert die Referenz auf einen Speicherbereich. Hier kann es leicht passieren, dass man Birnen und Äpfel verwechselt oder versucht miteinander zu vergleichen. |
AW: VAR oder nicht VAR Überlegungen
Zitat:
Aus diesem Grund steht bei mir vor jedem Parameter ein const, es sei denn ich benötige ein var oder ein out. |
AW: VAR oder nicht VAR Überlegungen
Zitat:
Unit A gehört zu Projekt A von 1990 Unit B gehört zu Projekt B von 2005 Unit C heißt eigentlich Hier_sind_alle_Proceduren_drinn_die_sich_in_den_le tzten_25_Jahren_angesammelt_haben.pas 2015 muss ich einen Fehler suchen und schaue mir eine Procedure an... Und wen da steht: Procedure GetPLZ2Ort(Var AAdresse:tAdresse); Bin ich mir sicher, egal ob es ein TObject oder ein Record ist, wenn ich Adresse.Ort := GetOrt(Adresse.PLZ); Bla bla bal Das meine Adresse die ich übergeben habe, sich auch ändert und nicht nur die lokale AAdresse. Mavarik |
AW: VAR oder nicht VAR Überlegungen
Wenn ich das jetzt richtig verstanden habe, dann hast Du in der Unit B aus einem Record "einfach" mal eine (Krüppel-)Klasse gemacht. Das wird zwar manchmal gerne propagiert, halte ich aber für nicht sooo gelungen, da "Verwechslungsgefahr" besteht.
Hier kehrt sich der "Vorteil", daß Pointer hinter normalen Namen versteckt werden, in einen Nachteil um, denn der Programmierer muß wissen was übergeben wird. Bei solchen Mißverständnissen gefällt mir die "Pointeritis" des Windows-API wieder richtig gut. Gruß K-H |
AW: VAR oder nicht VAR Überlegungen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:46 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