![]() |
Delphi-Version: 7
Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Hallo DPler,
Ich habe folgende Klasse geschrieben:
Delphi-Quellcode:
Diese Klasse benutze ich um in länger dauernden Prozeduren den Wartecursor anzuzeigen und automatisch den richtigen Cursor wiederherzustellen, nachdem die Prozedur beendet ist.
type
IWaitCursor = interface end; TWaitCursor = class (TInterfacedObject, IWaitCursor) private fCursor : TCursor; public constructor Create; destructor Destroy; override; end; implementation constructor TWaitCursor.Create; begin inherited; fCursor := Screen.Cursor; Screen.Cursor := crHourGlass; MainFrom.TrafficLight := tlRed; end; destructor TWaitCursor.Destroy; begin Screen.Cursor := fCursor; MainFrom.TrafficLight := tlGreen; inherited; end; Nun bekomme ich aber für jede Verwendung einen Hinweis vom Compiler, dass die variable nicht genutzt wird. Kann man das irgendwie für diese Fälle ausschalten?
Delphi-Quellcode:
procedure TMainForm.MyMethod;
var cur : IWaitCursor; begin cur := TWaitCursor.Create; // Auf 'cur' zugewiesener Wert wird niemals benutzt sleep(1000); end; |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
In diesem Fall könnte man ausnahmsweise with verwenden:
Delphi-Quellcode:
with TWaitCursor.Create do
sleep(1000); |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Zitat:
Delphi-Quellcode:
Geht auch und produziert keine Warnung. Warum eine Variable anlegen wenn man sie eh nicht verwendet?
procedure TMainForm.MyMethod;
begin TWaitCursor.Create; sleep(1000); end; |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Zitat:
Zitat:
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Stimmt. Dann halt mit Variable und try-finally :mrgreen:
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Erweitere die Klasse um eine
Delphi-Quellcode:
class function Construct : IWaitCursor;
Delphi-Quellcode:
dann kann das ohne Speicherleck und Warnung so benutzt werden
type
IWaitCursor = interface end; TWaitCursor = class (TInterfacedObject, IWaitCursor) private fCursor : TCursor; public constructor Create; destructor Destroy; override; class function Construct : IWaitCursor; end; implementation class function TWaitCursor.Construct : IWaitCursor; begin Result := TWaitCursor.Create; end; constructor TWaitCursor.Create; begin inherited; fCursor := Screen.Cursor; Screen.Cursor := crHourGlass; MainFrom.TrafficLight := tlRed; end; destructor TWaitCursor.Destroy; begin Screen.Cursor := fCursor; MainFrom.TrafficLight := tlGreen; inherited; end;
Delphi-Quellcode:
procedure Foo;
begin TWaitCursor.Construct; Sleep( 1000 ); end; Zitat:
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Nebenbei bemerkt, ist diese direkte Referenzierung
Delphi-Quellcode:
natürlich sehr suboptimal. Damit hast du der Klasse eine sehr starke Abhängigkeit gegeben, die man eigentlich vermeiden soll (eigentlich muss).
MainFrom.TrafficLight := tlRed;
Das solltest du anders lösen |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Hier eine Variante ohne diese Abhängigkeiten und Überflüssiges (z.B.
Delphi-Quellcode:
) und vor allem auch kaskadierbar
IWaitCursor
Delphi-Quellcode:
Beispiel
unit WaitCursor;
interface uses System.SysUtils, Vcl.Forms, Vcl.Controls; type TWaitCursor = class( TInterfacedObject ) private class var [weak] _Instance : TWaitCursor; class var _OnShow : TProc; class var _OnHide : TProc; private FCursor : TCursor; protected constructor Create; public destructor Destroy; override; class function Show : IInterface; class property OnShow : TProc read _OnShow write _OnShow; class property OnHide : TProc read _OnHide write _OnHide; end; implementation { TWaitCursor } constructor TWaitCursor.Create; begin inherited; FCursor := Screen.Cursor; Screen.Cursor := crHourGlass; if Assigned( _OnShow ) then _OnShow( ); end; destructor TWaitCursor.Destroy; begin _Instance := nil; Screen.Cursor := FCursor; if Assigned( _OnHide ) then _OnHide( ); inherited; end; class function TWaitCursor.Show : IInterface; begin if not Assigned( _Instance ) then _Instance := TWaitCursor.Create; Result := _Instance; end; end.
Delphi-Quellcode:
procedure Foo;
begin TWaitCursor.Show; Sleep( 1000 ); end; procedure Bar; begin TWaitCursor.Show; Foo; end; |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Ja, man kann solche Meldungen deaktivieren, aber mann kann den "Fehler" auch einfach beseitigen. :angel2:
Und am Einfachsten ist es, wenn man die ungenutzte Variable weglässt. Oder man macht z.B. ein
Delphi-Quellcode:
dahinter und nutzt die Variable.
if cur = nil then ;
Ach ja, die Variable weglassen und den Resultwert "ignorieren" geht nur, wenn diese Funktion nicht deaktiviert ist. Wobei das eigentlich nicht mehr vorkommen sollte, da es nur ein Kompilerschalter für die Unterstüzung von uraltem Code ist. (Abwärtzkompatibilität) siehe
Delphi-Quellcode:
/
{$X+}
Delphi-Quellcode:
{$EXTENDEDSYNTAX ON}
Und hier gibt es noch das Problem der impliziten Typumwandlung. Da man hier ja unbedingt das Interface braucht, müsste man ohne die Variable den Typ manuell in ein Interface umwandeln. Delphi legt bei Zwischenergebnissen und für nicht verwendete Result-Werte eine lokale Variable an, wobei es hier allerdings den Klassentyp verwendet und nicht das Interface. Also ich hätte da eine Class-Funktion in TWaitCursor eingebaut, welche das Interface als result liefert, womit man sich die manuellen umwandlungen überall erspart und das nur an einer Stelle macht. [edit] siehe das Beispiel vor mir. |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Im OP steht doch was von Delphi 7. Gab's da schon class vars, functions und properties?
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Zitat:
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Selbst wenn D7:
- Class-Functions gab es definitiv schon - Class-Var bin ich nicht mehr sicher, aber ich glaub schon und wenn doch nicht, dann kann man das auch anders lösen (z.B. globale Variable in der Implementation) Gab es nicht ein Feature-Request von mir, wo ich mir wünschte, daß dieses standardmäßig mit dem Delphi aus dem Profil gefüllt wird, oder wo standardmäßig "nichts" da ausgewählt ist? |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Weniger zur Technik, sondern zur Philosophie:
Zitat:
Delphi-Quellcode:
!), aber ich finde grade bei Dingen wie etwas, das in seinem Konstruktor und Destruktor aktiv das Gesamtbild des Systems verändert es nicht angebracht, das automatisch ablaufen zu lassen wenn es out of scope geht.
[weak]
Habe ich ein
Delphi-Quellcode:
und jemand spaltet mir das, ohne es besser zu wissen in
procedure aufwändigeAufgabe();
begin // Schritt 1 TWaitCursor.Show(); doStuff(); doEvenMoreStuff(); // Schritt 2 transferMoney(); logStuff(); end;
Delphi-Quellcode:
auf, ist das Stundenglas nur noch für Schritt 1 zu sehen. Ja, hätte Refactor-Man es richtig gemacht, hätte er es in
procedure aufwändigeAufgabe();
begin schritt1(); schritt2(); end; procedure schritt1(); begin TWaitCursor.Show(); doStuff(); doEvenMoreStuff(); end; [...]
Delphi-Quellcode:
gelassen. Aber ich finde den Fehler kann man zu einfach machen.
aufwändigeAufgabe()
Ich packe gerne Dinge wie eine lokale
Delphi-Quellcode:
in eine interface-referenzierte Tonne um mir den try..finally-Block für das Aufräumen zu sparen, aber grade im Fall mit dem Cursor wäre mein persönlicher Geschmack wirklich weiterhin ein waschechter try..finally-Block. Da sieht man auch auf den ersten Blick was man hat- Ohne zu wissen, was sich hinter den
TStringList
Delphi-Quellcode:
-Kulissen abspielt.
TWaitCursor
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Unabhängig davon könnte man dem TE -da die Frage schon beantwortet wurde- den Tipp geben, hier keine Klasse zu erzeugen, sondern eher einen kleinen UI-Controller, der das übernimmt. Da Delphi das Paradigma 'Wer Dreck macht, muss aufräumen' vorgibt (Create/Free, Begin/EndUpdate usw.) sollte man das imho hier auch bewusst so umsetzen:
Delphi-Quellcode:
Und wenn Refactor-Man jetzt loslegt, muss er ja die Try-Finally-Blöcke zusammen lassen.
...
UIController.BeginWaitCursor; Try DoFoo(); DoBar(); UIController.BeginSQLWaitCursor; Try DoDatabaseStuff(); Finally UIController.EndWaitCursor; End; DoEvenMoreStuff(); Finally UIController.EndWaitCursor; End; ... Es dürfte in aktuellen Delphis auch mit Lambda-Ausdrücken gehen...
Delphi-Quellcode:
Da jetzt gerade ein Interface zu verwenden, erscheint mir etwas unglücklich.
Procedure WaitCursor (a : Action); // Oder wie das auch immer deklariert wird
begin oldCursor := Screen.Cursor; Screen.Cursor := clWait; try Action(); finally Screen.Cursor := oldCursor; End End; |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
@Dejan Vu
Wenn es danach geht, muss man die gesamte Vorgehensweise in Frage stellen. Denn Sinn macht das hier nur, wenn der echte Code in einem Thread gestartet wird (oder - igitt - mit
Delphi-Quellcode:
rumhantiert wird), ansonsten sieht man davon eher recht wenig (z.B. das Setzen des TrafficLights im Ausgangsbeitrag), da der MainThread blockiert ist.
Application.ProcessMessages
Wenn das aber in einem Thread erfolgt, dann wird der Cursor viel zu früh wieder zurück gesetzt. |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Hallo zusammen,
mir ist schon des öfteren mal eine Konstruktion wie
Delphi-Quellcode:
über den Weg gelaufen.
Myclass.Create;
Myclass.Machwas; Meiner Meinung nach richtig wäre
Delphi-Quellcode:
Da erstere Version auch funktioniert (?) könntet Ihr mich einmal aufklären was dahinter steckt?
Wert:=Myclass.Create;
Wert.Machwas; Wert.Free; Gruß K-H |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Es ist ein Konstruktoraufruf ohne das die zurückgegeben Referenz in einer Variable gespeichert wird
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Zitat:
Nja, das ist im Prinzip ein
Delphi-Quellcode:
(ohne Klasse), nur daß man den Code aufgeräumt hat und es in der zugehörigen Klasse positionierte.
procedure ShowWaitCursor;
Und nur weil man es ohne explizite Referenz nutzen kann
Delphi-Quellcode:
verbietet es keiner, wenn man in Sonderfällen dennoch eine Referenz verwendet.
begin
TWaitCursor.Show; // oder als einfache Funktion "ShowWaitCursor;" ... end; z.B.:
Delphi-Quellcode:
begin
X := TWaitCursor.Show; try ... finally X := nil; // oder X.Hide; end; ... end; |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Falls ohne T, dann wird der Konstruktor einfach als normle Methode auf eine viorhandene Instanz angewendet.
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Wenn
Delphi-Quellcode:
ein Klassentyp ist und dann muss
MyClass
Delphi-Quellcode:
eine
MyClass.MachWas
Delphi-Quellcode:
sein.
class procedure
Daraus folgt weiterhin, dass mit
Delphi-Quellcode:
ein Speicherleck erzeugt wird.
MyClass.Create;
Wenn
Delphi-Quellcode:
ist (Instanz-Variable), dann wird mit
MyClass : TMyClass;
Delphi-Quellcode:
der
MyClass.Create;
Delphi-Quellcode:
nochmals durchlaufen ohne eine weitere Instanz zu erzeugen. Dazu muss aber
constructor
Delphi-Quellcode:
schon mit einer gültigen Instanz belegt sein.
MyClass
So aus dem Kontext herausgerissen, kann man dazu also herzlich wenig sagen, ausser im Nebel herumstochern. Zitat:
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Wow, da ist man mal für drei kurze Stunden nicht in der DP und schon hat man nen Haufen antworten.
@SirRufo Die Lösung mit dem Construct ist schonmal sehr gut, das werde ich auf jeden Fall so machen. Da ich bei diesem Projekt noch mit Delphi 7 arbeiten muss, kann ich leider keine [Attribute] und anonymen Methoden verwenden, dass entkoppeln werde ich also anders machen müssen. Danke an alle. |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Zitat:
Delphi-Quellcode:
wird nur für ARC Compiler benötigt, kannst du also mit Compilerschaltern ausklammern.
[weak]
Anstatt der anonymen Methoden nimmst du einfach
Delphi-Quellcode:
.
TMethod = procedure of object;
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Das
Delphi-Quellcode:
-Attribut ist aber sowieso in allen Compilern implementiert.
[weak]
Mann kann es also problemlos überall angeben, auch wenn es nicht überall ausgewertet/beachtet wird. Auch wenn es "aktuell" nur von den mobilen Compilern ausgewertet wird, hab ich das dennoch bei einem aktuellen Projekt überall mit angegeben. Indirekt hat man so auch eine Dokumentationen der nichtgezählten Referenzen. |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Zitat:
vielen Dank K-H |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Hallo,
was mich interessieren würde: Gibt es keinen Compilerschalter, um genau diese Warnung zu unterdrücken ? Heiko |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Doch, aber besser wäre es die Fehler wegzumachen, da man sonst neue Fehler nicht mehr sieht.
Delphi-Quellcode:
{$WARN ...}
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Soweit ich weiß, kann man zwar Warnungen gezielt abschalten, Hinweise aber nur global.
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Laut OH ist es lokal.
Das wäre also von da wo man es deaktiviert weg, bis dahin man es wieder aktiviert und auch nur in der aktuellen Unit. (Außer man kann sowas in den Projektoptionen nochmals angeben, was dann aber nur den Defaultwert ändert, welcher bei Begin jeder Unit gilt) |
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Was ich meinte: man kann ganz bestimmte Warnungen abschalten (z.B. SYMBOL_PLATFORM), bei Hinweisen aber nur alle oder keine.
|
AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
Aso, joar, das stimmt leider.
z.B. warum bekommt ich "platform"-Warnungen, für Nur-Windows-Code, wenn ich in der VCL arbeite ... da gibt es nur Windows und somit sind diese Warnungen nuztlos. Oder vom Debugger kann man bestimmte Exceptions ignorieren, aber ich würder da gern auch abhängig von der Message oder der Auslösecodestelle (Unit) bestimmte Exceptions ignorieren können und nicht gleich alle dieses Typs. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:24 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