2012-04-01 15 views
4

Ich habe ein paar verschiedene Klassen, deren Herkunft eine andere Klasse ist. Ich habe eine Eigenschaft, die auf alle anderen Klassen erweitert wird. Aber unterschiedliche Klassen behandeln diese Eigenschaft anders. Also ich möchte dies tun:Delphi Objekt auswählen nach unbekannter Klassenart

TClass (ObjectPointer) .Eigenschaft: = Wert;

Aber TClass ist unbekannt Klassentyp

Kann ich etwas tun, wie folgt aus:

ObjectPointer.ClassType (ObjectPointer) .Property: = Wert

oder diese

var 
    ClassRef: TClass; 
begin 

    ClassRef := Sender.ClassType; 
    ClassRef(ObjectPointer).DoStuff 
    end; 

Gibt es eine Möglichkeit, dies in Delphi ohne Verwendung von if-Anweisung zu tun

+0

Welche Version von Delphi haben Sie? Ich frage, weil die Antwort Laufzeitinformation (RTTI) beinhaltet, und moderne Versionen von Delphi haben bessere Fähigkeiten in diesem Bereich. –

+0

Ich benutze Delphi 7 zweite Ausgabe – TreantBG

+0

@David, auch wenn Sie Delphi XE2 haben, können Sie noch 'TypInfo.pas' verwenden – TLama

Antwort

8

Bitte beachten Sie, der Code aus diesem Beitrag funktioniert nur für veröffentlichte Eigenschaften!

Um Ihre Frage zu beantworten wenn es einen Weg gibt, ohne einen Eigenschaftswert zu setzen, wenn Anweisung, folgende überladene Funktionen überprüfen.

Die erste ist für Char, String, Variante, Integer, 64-Bit-Ganzzahl, Float, Enumeration, Set und dynamischen Array-Typ von Eigenschaften (Puh). Der zweite ist nur für Eigenschaften des Klassentyps. Beide kehren True, wenn bestimmte Eigenschaft vorhanden ist und der Wert oder die Objektinstanz successfuly zugewiesen, ansonsten False:

uses 
    TypInfo; 

function TrySetPropValue(AInstance: TObject; const APropName: string; 
    const AValue: Variant): Boolean; overload; 
begin 
    Result := True; 
    try 
    SetPropValue(AInstance, APropName, AValue); 
    except 
    Result := False; 
    end; 
end; 

function TrySetPropValue(AInstance: TObject; const APropName: string; 
    AValue: TObject): Boolean; overload; 
begin 
    Result := True; 
    try 
    SetObjectProp(AInstance, APropName, AValue); 
    except 
    Result := False; 
    end; 
end; 

Und die Nutzung; wenn die Memo1.Lines der gesetzt ist, wird die zweite Version von TrySetPropValue genannt:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Strings: TStringList; 
begin 
    TrySetPropValue(Memo1, 'Width', 250); 
    TrySetPropValue(Memo1, 'Height', 100); 
    TrySetPropValue(Memo1, 'ScrollBars', ssBoth); 

    Strings := TStringList.Create; 
    try 
    Strings.Add('First line'); 
    Strings.Add('Second line'); 
    TrySetPropValue(Memo1, 'Lines', Strings); 
    finally 
    Strings.Free; 
    end; 

    if not TrySetPropValue(Memo1, 'Height', 'String') then 
    ShowMessage('Property doesn''t exist or the value is invalid...'); 
    if not TrySetPropValue(Memo1, 'Nonsense', 123456) then 
    ShowMessage('Property doesn''t exist or the value is invalid...'); 
end; 
+0

Ok aber was muss ich in meiner Klasse machen, denn wenn ich das benutze kommt immer ein Fehler "Eigenschaft asd existiert nicht "aber ich habe diese veröffentlichte Eigenschaft - Eigenschaft asd: doppelt lesen ActTime schreiben ActTime; – TreantBG

+1

Der Code von diesem Beitrag funktioniert nur für 'published' Eigenschaften. Veröffentlichtes Eigentum bedeutet nicht nur, dass Sie es in einer Klasse exponiert haben, es muss im publizierten Bereich sein. – TLama