2009-06-10 18 views
4

Ok undefiniert sein, ich habe die folgende Funktion:Rückgabewert der Funktion könnte

function TfPackagedItemEdit.GetRTFDescription: TStringList; 
begin 
    Result.Text := richDescription.Lines.Text; //stringlist 
end; 

Der Compiler generiert die folgende Warnung vor dieser Zeile:

[DCC Warnung] W1035 Rückgabewert der Funktion ‚GetRTFDescription 'könnte undefined sein

Irgendwelche Ideen, wie ich diese Warnung aufklären kann? (außer es nur Drehen in den Projektoptionen aus)

Ich habe versucht:

function TfPackagedItemEdit.GetRTFDescription: TStringList; 
begin 
    Result.Text := ''; 
    Result.Text := richDescription.Lines.Text; 
end; 

Aber das funktioniert auch nicht.

+7

Warnungen sind Sie Freund. 99% der Zeit lassen sie dich über etwas sehr Schlechtes wissen. –

+0

LOL, ich habe gerade ein Problem untersucht, das damit in Zusammenhang zu stehen schien - ich wollte sehen, ob ich Recht hatte (definitiv NICHT OK, wenn man annimmt, dass eine boolesche Funktion false zurückgibt, wenn man vor der Aufgabe verschwindet). Ich lag richtig. Wichtiger Hinweis: Deaktivieren Sie die Compilerwarnungen nicht. Dieses spezielle Projekt hatte sie alle ausgeschaltet. D'OH! (nicht ich, btw.) –

Antwort

21

Die Variable wird standardmäßig nicht initialisiert. Es bezieht sich nicht automatisch auf eine vom Compiler generierte Instanz TStringList. Sie müssen Result einen Wert zuweisen. Das bedeutet eine Zeile wie diese irgendwo in Ihrem Code mit:

Result := ...; 

Ein Ausdruck wie Result.X ist der Wert Result, um das Lesen einen Verweis auf seine X Mitglied zu bekommen, so dass Sie Result gegeben haben brauchen eine Wert bereits. Larry's answer demonstriert, wie man das macht. Es generiert eine neueTStringList Instanz, so dass der Aufrufer dieser Funktion irgendwann Free für dieses Objekt aufrufen muss.

Aber in einem Kommentar erwähnen Sie, dass Sie diese Funktion als Eigenschaft Accessor verwenden. Es ist unangenehm für Anrufer, Objekte jedes Mal freizugeben, wenn sie eine Eigenschaft lesen, so dass Ihr gesamter Plan unangemessen ist. Da es aussieht wie du bist versuchen, den Beschreibungstext zu belichten, können Sie diese stattdessen berücksichtigen:

function TfPackagedItemEdit.GetRTFDescription: TStrings; 
begin 
    Result := richDescription.Lines; 
end; 

Hinweis zuerst, dass ich die Rückkehr Typ TStrings geändert haben, die im Wesentlichen die abstrakte Basisklasse ist alle Arten von String-Listen in der VCL. TStringList ist ein Nachkomme, aber TRichEdit.Lines verwendet TStringList nicht. Stattdessen verwendet es einen speziellen TStrings Nachkommen, der mit dem zugrunde liegenden Rich-Edit-Steuerelement interagieren kann.

Als nächstes beachten Sie, dass ich keine neuen Objekte erstellt habe. Stattdessen habe ich einen Verweis direkt auf die Eigenschaft Lines des Steuerelements zurückgegeben. Benutzer Ihrer RTFDescription-Eigenschaft müssen sich nicht mehr darum kümmern, das Objekt zu befreien, das sie erhalten.

+0

Aus Sicherheitsgründen würde ich auch eine Überprüfung hinzufügen, um sicherzustellen, dass richDescription ebenfalls zugewiesen wird, nur um den Fall zu schützen, wenn GetRTFDescription aufgerufen wird und richDescription noch nicht erstellt wurde. Es ist einfacher, nach dem Aufruf von GetRTFDescription nach Nil zu suchen, als nach Ausnahmen zu suchen, die leicht zu handhaben sind. – skamradt

+0

Das ist die Art von was eine Behauptung ist. Es wird angenommen, dass alle internen Komponenten zugewiesen werden, bevor jemand damit anfängt, mit Eigenschaften zu spielen. Wenn dies nicht der Fall ist, liegt ein Programmierfehler vor, kein Benutzerfehler und sollte vor dem Versand behoben werden. –

14

Der Compiler ist korrekt. Das Ergebnis wird standardmäßig nicht initialisiert. Versuchen

function TfPackagedItemEdit.GetRTFDescription: TStringList; 
begin 
    Result = TStringList.Create(); 
    Result.Text := richDescription.Lines.Text; 
end; 

Update: Nachdem die Kommentare bewerten ich das ursprüngliche Plakat tatsächlich glauben, so etwas wie dies wünscht.

function TfPackagedItemEdit.GetRTFDescription: String; 
begin 
    Result := richDescription.Lines.Text; 
end; 
+6

Und vergessen Sie nicht, dass dies bedeutet, dass der Aufrufer dafür verantwortlich ist, den Speicher freizugeben, der von GetRTFDescription zugewiesen wurde. –

+0

Ich hätte gerne eine Klarstellung dazu. Wie würde ich die Erinnerung freigeben? Ich habe dies gerade als Immobilien-Getter bezeichnet. – croceldon

+3

Verwenden Sie auch "Result.Assign (richDescription.Lines);" Für die Geschwindigkeit verkettet der Code alle Zeilen zu einer Zeichenfolge, nur um die Zeichenfolge wieder in Zeilen aufzuteilen. – mghie

2

Ich stimme zu, dass die Rückkehr einer einfachen String wahrscheinlich die beste Lösung wäre, oder zumindest wird es freundlich zu bedienen sein.

Alternativ können Sie den Verweis auf die TStringList zurückkehren, die die schnellste Lösung, wenn Sie viel Text sind mit ..

function TfPackagedItemEdit.GetRTFDescription: TStringList; 
begin 
    Result := richDescription.Lines; 
end; 
Verwandte Themen