Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Gehen strings als Eigenschaftsnamen? Wenn ja wie? (https://www.delphipraxis.net/198143-gehen-strings-als-eigenschaftsnamen-wenn-ja-wie.html)

ScharfeMietze 7. Okt 2018 10:25

Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Delphi-Quellcode:
           
if (LowerCase(Ljtr.Path) = 'groupoptions.can_send_other_messages') and (Ljtr.TokenType = TJsonToken.Boolean) then
              begin
                LBotOptions.cs:= Ljtr.Value.ToString.ToBoolean;
              end
das ist typisches konstruct
ich hätte aber gerne sowas wie
Delphi-Quellcode:
try
if (Ljtr.TokenType = TJsonToken.Boolean) then LBotOptions.'can_send_other_messages' := Ljtr.Value.ToString.ToBoolean;
.....
gibt es sowas?

Freu mich auf antworten ....
Gruß die Mietze

mkinzler 7. Okt 2018 10:29

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Was hast Du vor?

Eigentlich sind Eigenschaftsnamen ja Strings. Willst Du die Eigenschaft abhand eines Inhalts eines Strings auswählen?

ScharfeMietze 7. Okt 2018 10:48

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Ja das ist der Plan. Ich bekomme via jsonstring Eigenschaftswerte die ich (je nach bedarf) im "Bauplan" der Botoptions verankere.

Ich möchte mir ersparen dann jede Eigenschaft im Code beim einlesen nochmal verankern zu müssen.

Gruß

Delphi.Narium 7. Okt 2018 11:14

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Suchst Du sinngemäß sowas?
Delphi-Quellcode:
uses TypInfo;

procedure SetProperty(AComponent: TComponent; sProperty, sValue: string);
var
  PropInfo: PPropInfo;
begin
  if Assigned(AComponent) then begin
    PropInfo := GetPropInfo(AComponent.ClassInfo, sProperty);
    if Assigned(PropInfo) then begin
      case PropInfo^.PropType^^.Kind of
        tkString,
        tkLString,
        tkWString: SetStrProp(AComponent, PropInfo, sValue);
        tkInteger: SetOrdProp(AComponent, PropInfo, StrToInt(sValue))
      else
        SetStringsProperty(AComponent, PropInfo, sValue);
      end;
    end;
  end;
end;

procedure SetStringsProperty(AComponent: TComponent;
                             PropInfo: PPropInfo;
                             sValues: string);
var
  AStrings: TStringList;
  sBuffer: string;
  i: Integer;
begin
  AStrings := TStringList.Create;
  i := Pos(FSeparator, sValues);
  while (i > 0) do begin
    sBuffer := Copy(sValues, 1, i-1);
    Delete(sValues, 1, i - 1 + Length(FSeparator));
    i := Pos(FSeparator, sValues);
    AStrings.Add(Trim(sBuffer));
  end;
  if (Length(Trim(sValues)) > 0) then AStrings.Add(Trim(sValues));
  SetOrdProp(AComponent, PropInfo, LongInt(Pointer(AStrings)));
  AStrings.Free;
end;
Im Zweifelsfalle mal die Unit TypInfos (so hieß sie zu Dlephi 7-Zeiten) durchforsten. Da müsste so etliches zum Abfragen uns Setzen von Eigenschaften (über den Namen) drinne sein.

ScharfeMietze 7. Okt 2018 11:27

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Das muss ich mal sacken lassen und werde es gleich mal probieren! Wenn das geht wäre das natürlich absolut Hammer!!

ScharfeMietze 7. Okt 2018 12:22

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Da ich mit PPropInfo; und co noch nicht viel zu tun hatte muss ich nochmal nachfragen ob ich es richtig verstehe, da ich z.B beim else der procedure hänge.

Delphi-Quellcode:
procedure SetProperty(AComponent: TComponent; sProperty, sValue: string);
bedeutet doch
aComponent = Bauplan
sProperty = poperty des Bauplans
sValue = Wert der an das property des Bauplans gesendet wird...
ist das soweit richtig?


Delphi-Quellcode:
  if Assigned(AComponent) then begin
    PropInfo := GetPropInfo(AComponent.ClassInfo, sProperty);
Wenn der Bauplan vorhanden ist, schreibe in PropInfo den "string" aus sproperty.


Delphi-Quellcode:
if Assigned(PropInfo) then begin
Wenn das Property vorhanden ist, schreibe den (string) Wert aus sValue in das Property.

hab ich das soweit richtig verstanden oder bin ich da schon falsch??

Weil weiterführende Frage ist natürlich (falls ich oben richtig liege)

Delphi-Quellcode:
        tkWString: SetStrProp(AComponent, PropInfo, sValue);
        tkInteger: SetOrdProp(AComponent, PropInfo, StrToInt(sValue))

Wenn ein Boolean/Integer als Wert sValue habe, reicht es die beiden Zeilen anzupassen? Wenn ja wie muss das aussehen?

und
Delphi-Quellcode:
procedure SetStringsProperty(AComponent: TComponent;
                             PropInfo: PPropInfo;
                             sValues: string);
was diese procedure tut ist mir bisher nicht klar?!?:shock:

Gruß Mietze (momentan noch gar nicht scharf :lol:)

Delphi.Narium 7. Okt 2018 13:09

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Prinzipell hast Du das richtig verstanden, Du musst quasi "nur" die Case-Abfrage im Beispiel an Deine Bedürfnisse anpassen.

SetStringsProperty befüllt eine Eigenschaft vom Typ TStrings.

Schau Dir bitte die Unit TypInfo (bzw. das Gegenstück Deiner Delphiversion) an.

Bei allen Methoden zum Lesen / Schreiben gilt eigentlich folgender Aufbau:

Delphi-Quellcode:
Welches Objekt, welche Eigenschaft, welcher Wert
Siehe u. a.: http://docwiki.embarcadero.com/Libra...System.TypInfo

Für die unterschiedlichen Eigenschaften gibt es jeweils entsprechende Getter und Setter. Die musst Du "nur" entsprechend Deiner Datentypen aufrufen.

Jetzt rate ich mal, da mir das Ganze irgendwie zu abstrakt ist und ich nicht über eine passende Delphiversion verfüge (sinngmäß sowas):
Delphi-Quellcode:
if (Ljtr.TokenType = TJsonToken.String) then begin
  if (LowerCase(Ljtr.Path) = 'irgendwas_was_ein_String_Ist') then begin
    SetStrProp(LBotOptions,'ZuSetzendeStringEigenschaft',Ljtr.Value.ToString);
  end else
  if (LowerCase(Ljtr.Path) = 'anderer_String') then begin
    SetStrProp(LBotOptions,'AndereStringEigenschaft',Ljtr.Value.ToString);
  end;
end else
if (Ljtr.TokenType = TJsonToken.Integer) then begin
  if (LowerCase(Ljtr.Path) = 'irgendwas_was_ein_Integer_Ist') then begin
    SetInt64Prop(LBotOptions,'ZuSetzendeIntegerEigenschaft',Ljtr.Value.ToInteger);
  end else
  if (LowerCase(Ljtr.Path) = 'anderer_String') then begin
    SetInt64Prop(LBotOptions,'AndereIntegerEigenschaft',Ljtr.Value.ToInteger);
  end;
end else
// alle weiteren Typen abarbeiten und die jeweilige SetGewünschterTypProp nutzen.
Oder, damit es kürzer und (eventuell) lesbarer wird:
Delphi-Quellcode:
var
  sLowerPath : String;
  sEigenschaft : String;
begin
  sLowerPath : LowerCase(Ljtr.Path);
  if (Ljtr.TokenType = TJsonToken.String) then begin
    if (sLowerPath = 'irgendwas_was_ein_String_Ist') then sEigenschaft := 'ZuSetzendeStringEigenschaft'
    else if (sLowerPath = 'anderer_String') then sEigenschaft'AndereStringEigenschaft';
    SetStrProp(LBotOptions,sEigenschaft,Ljtr.Value.ToString);
  end else
  if (Ljtr.TokenType = TJsonToken.Integer) then begin
    if (sLowerPath = 'irgendwas_was_ein_Integer_Ist') then sEigenschaft := 'ZuSetzendeIntegerEigenschaft'
    else if (sLowerPath = 'anderer_Integer') then sEigenschaft := 'AndereIntegerEigenschaft';
    SetInt64Prop(LBotOptions,sEigenschaft,Ljtr.Value.ToInteger);
  end else
  // alle weiteren Typen abarbeiten und die jeweilige SetGewünschterTypProp nutzen.
end;
oder eventuell:
Delphi-Quellcode:
var
  sLowerPath : String;
  sEigenschaft : String;
begin
  sLowerPath : LowerCase(Ljtr.Path);
  if (sLowerPath = 'irgendwas_was') then sEigenschaft := 'WirdZuEigenschaft'
  else if (sLowerPath = 'was_anderes') then sEigenschaft := 'AndereEigenschaft'
  else if ...;
  case Ljtr.TokenType of
    TJsonToken.String : SetStrProp(LBotOptions,sEigenschaft,Ljtr.Value.ToString);
    TJsonToken.Integer : SetInt64Prop(LBotOptions,sEigenschaft,Ljtr.Value.ToInteger);
    // alle weiteren Typen abarbeiten und die jeweilige SetGewünschterTypProp nutzen.
  else
    // Fehlermeldung, weil ein Typ vergessen wurde?
  end;
end;

ScharfeMietze 7. Okt 2018 13:49

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Delphi-Quellcode:
            if (Ljtr.TokenType = TJsonToken.String) then
              begin
              if (LowerCase(Ljtr.Path) = 'groupoptions.chatid') then LBotOptions.chatid:= Ljtr.Value.ToString
              else
              if (LowerCase(Ljtr.Path) = 'groupoptions.antispammessage') then LBotOptions.AntiSpamMessage:= Ljtr.Value.ToString
              else
              if (LowerCase(Ljtr.Path) = 'groupoptions.creator') then LBotOptions.Creator:= Ljtr.Value.ToString
              else
              if (LowerCase(Ljtr.Path) = 'groupoptions.blacklist') then LBotOptions.blacklist:= Ljtr.Value.ToString
              else
              if (LowerCase(Ljtr.Path) = 'groupoptions.whitelist') then LBotOptions.whitelist:= Ljtr.Value.ToString
              else
              if (LowerCase(Ljtr.Path) = 'groupoptions.welcomemessage') then LBotOptions.welcomemessage:= Ljtr.Value.ToString
              end
........
Wir sind ja fast da wo ich hin will! Also müsste doch der Part oben durch diesen ersetzbar sein oder? ( ja ich habe den Code seit dem Erstellpost aufgrund der Antwort schon begonnen umzustellen)
Delphi-Quellcode:
            if (Ljtr.TokenType = TJsonToken.String) then
              begin
                SetStrProp(LBotOptions,LowerCase(Ljtr.Path),Ljtr.Value.ToString)
              end;

Delphi.Narium 7. Okt 2018 13:52

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Ja, sollte meiner Meinung nach passen.

ScharfeMietze 7. Okt 2018 14:02

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Ich bin ja mal gespannt... ich werde heute zwar nicht mehr dazu kommen es einzubauen, berichte aber wenn es so weit ist,
Weil mal ganz ehrlich das erspart viel Arbeit ....
Wenn das wirklich funzt weiß ich gar nicht wie dankbar ich sein werde, die geschenkte Lebenszeit ist ja kaum aufzuwiegen :-D:-D

Delphi.Narium 7. Okt 2018 14:29

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Wenn die Eigenschaften von LBotOptions genauso heißen, wie der Path in Ljtr, dann geht das:
Delphi-Quellcode:
  if (Ljtr.TokenType = TJsonToken.String) then begin
    SetStrProp(LBotOptions,Ljtr.Path,Ljtr.Value.ToString)
  end;
Beim letzten Beispiel von Dir haben wir aber (u. a.)
Delphi-Quellcode:

if (LowerCase(Ljtr.Path) = 'groupoptions.chatid') then LBotOptions.chatid:= Ljtr.Value.ToString;
Damit passen dann Path und Eigenschaftsname nicht mehr zueiander. Da müsste die Routine zur Zuweisung etwas "überarbeitet" werden:
Delphi-Quellcode:
if (Ljtr.TokenType = TJsonToken.String) then begin
  SetStrProp(LBotOptions,AnsiReplaceText(Ljtr.Path,'groupoptions.',''),Ljtr.Value.ToString);
end;

ScharfeMietze 7. Okt 2018 14:39

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Er behauptet die Eigenschaft würde nicht existieren, obwohl sie das definitiv tut ?!?
Was übersehe ich ?!?

Delphi.Narium 7. Okt 2018 14:50

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Zeig' bitte mal die vollständige Definition von TLBotOptions und ein Beispiel dessen, was in Ljtr vorzufinden ist.

Was ich nicht weiß: Ist die Suche nach Eigenschaften eventuell casesensitiv?

ScharfeMietze 7. Okt 2018 15:00

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Delphi-Quellcode:
  TBotOptions = class
  private
    FChatID: string;
    FRestrictNewUser: Boolean;
    Fcan_send_other_messages: Boolean;
    Fcan_send_messages: Boolean;
    Fcan_add_web_page_previews: Boolean;
    Fcan_send_media_messages: Boolean;
    FAntiSpamMessage: string;
    FDeleteSpam: Boolean;
    FCreator: string;
    Fwhitelist: string;
    Fblacklist: string;
    Frestrict_time: Integer;
    Fwelcomemessage: string;
    FStart: Boolean;

    procedure Set_ChatID(const Value: string);
    procedure Set_AntiSpamMessage(const Value: string);
    procedure Set_can_add_web_page_previews(const Value: Boolean);
    procedure Set_can_send_media_messages(const Value: Boolean);
    procedure Set_can_send_messages(const Value: Boolean);
    procedure Set_can_send_other_messages(const Value: Boolean);
    procedure Set_DeleteSpam(const Value: Boolean);
    procedure Set_RestrictNewUser(const Value: Boolean);
    procedure Set_Creator(const Value: string);
    procedure Set_blacklist(const Value: string);
    procedure Set_whitelist(const Value: string);
    procedure Set_restrict_time(const Value: Integer);
    procedure Set_welcomemessage(const Value: string);
    procedure Set_Fstart(const Value: Boolean);

    { private declarations }
  protected
    { protected declarations }
  public
    property chatid:string           read FChatID         write Set_ChatID;
    property deletespam:Boolean      read FDeleteSpam     write Set_DeleteSpam;
    property restrictnewuser:Boolean read FRestrictNewUser write Set_RestrictNewUser;
    property antispammessage:string read FAntiSpamMessage write Set_AntiSpamMessage;
    property can_send_messages:Boolean read Fcan_send_messages write Set_can_send_messages;
    property can_send_media_messages:Boolean read Fcan_send_media_messages write Set_can_send_media_messages;
    property can_send_other_messages:Boolean read Fcan_send_other_messages write Set_can_send_other_messages;
    property can_add_web_page_previews:Boolean read Fcan_add_web_page_previews write Set_can_add_web_page_previews;
    property creator:string read FCreator write Set_Creator;
    property blacklist:string read Fblacklist write Set_blacklist;
    property whitelist:string read Fwhitelist write Set_whitelist;
    property restrict_time:Integer read Frestrict_time write Set_restrict_time;
    property welcomemessage: string read Fwelcomemessage write Set_welcomemessage;
    property start :Boolean read FStart write Set_Fstart;
    { public declarations }


  end;
Ist die aktuelle class ...

und das Json
Code:
  "groupoptions": {
    "ChatID": "-xxxxxx",
    "DeleteSpam": true,
    "RestrictNewUser": true,
    "AntiSpamMessage": "SpamPost",
    "can_send_messages": true,
    "can_send_media_messages": false,
    "can_send_other_messages": false,
    "can_add_web_page_previews": false,
    "Creator": "blablub",
    "blacklist": "blablub",
    "whitelist": "",
    "restrict_time": 15,
    "welcomemessage": "",
    "start": true
  },
Wegen dem Case insensitive LowerCase ich es ja vorher runter ......

Ps: http://docwiki.embarcadero.com/CodeE...RTL.JSONReader ist die komponente die mir das Json ließt....

Delphi.Narium 7. Okt 2018 15:30

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Zitat:

Zitat von ScharfeMietze (Beitrag 1415145)
Wegen dem Case insensitive LowerCase ich es ja vorher runter ......

Dachte halt, wenn Delphi casesensitive sucht, könnte das ein Problem sein, wenn die Eigenschaften in 'ner Kombination aus Groß-/Kleinschreibung vorliegen. Da dem nicht so ist, können wir den Fehler schonmal ausschließen.

Momentan hab' ich keine Idee, was da jetzt die Fehlerursache sein könnte.

Oder liegt es eventuell dadran:
Delphi-Quellcode:
TBotOptions = class
?

Damit man die TypInfo nutzen kann, muss als Vorfahre mindestens TObject gegeben sein:
Delphi-Quellcode:
TBotOptions = class(TObject)

ScharfeMietze 7. Okt 2018 15:36

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Delphi-Quellcode:
  TBotOptions = class (TObject)
wurde geändert ... gleicher Fehler *sniff*

Delphi.Narium 7. Okt 2018 15:49

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Sorry, keine Ahnung:

Debugger marsch:

BreakPoint vor SetStrProp und dann in Einzelschritten bis in die tiefsten Tiefen und jeweils merken, aufschreiben, sagen (wie auch immer) bis wo Du gekommen bist bzw. an welcher Stelle die Fehlermeldung produziert wird.

Aber:

Beim manuellen durchgehen der TypInfo habe ich versucht, einzeln mal die Methoden zu verstehen und dann daraus zu kombinieren:

Mir scheint, damit das Ganze funktioniert, müssen die "zu verarbeitenden" Eigenschaften unter
Delphi-Quellcode:
published
stehen,
Delphi-Quellcode:
public
reicht nicht aus.

Also Vorfahre mindestens TObject und Eigenschaften müssen published sein.

Wer was anderes weiß: Bitte immer her damit ;-)

ScharfeMietze 7. Okt 2018 16:16

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Also nachdem ich nun einen Schreibfehler ausgemerzt habe , bekomme ich als ausgabe
Von Public habe ich alles in published verschoben ....
Inkompatible Typen: 'TComponent' und 'TBotOptions'

Delphi.Narium 7. Okt 2018 16:33

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
An welcher Stelle?

Da
Delphi-Quellcode:
procedure SetProperty(AComponent: TComponent; sProperty, sValue: string);
?
Dann in der Routine aus
Delphi-Quellcode:
AComponent: TComponent
bitte
Delphi-Quellcode:
AObject: TObject
und im weiteren der Routine aus AComponent jeweils AObject machen.

Wenn das nicht die Fehlerstelle ist, bitte den kompletten, aktuellen Quelltext posten, so ist das doch sehr abstrakt und kaum zu handhaben.

ScharfeMietze 7. Okt 2018 16:53

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Ich bin einen Kleinen schritt weiter !!
Delphi-Quellcode:
rocedure SetProperty2(sProperty, sValue: string);
var
  LPropList: PPropList;
  LPropCount, I: Integer;
begin
  LPropCount := GetPropList(LBotOptions, LPropList);
  try
  for I := 0 to LPropCount-1 do
    begin
    if LPropList[I].Name = sProperty then
      begin
       ShowMessage(LPropList[I].Name);
       Break
      end;
    end;
  finally
    FreeMem(LPropList);
  end;
end;
Damit finde ich nun die richtige eigenschaft. Nun brauche ich noch den Weg wie ich die Eigenschaft schreibe???? Ich hangel mich hier von ast zu ast ... Wenn jemand dafür noch ein Weg hat wäre das super!

Delphi.Narium 7. Okt 2018 17:32

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Zitat:

Zitat von ScharfeMietze (Beitrag 1415158)
Ich bin einen Kleinen schritt weiter !!
Delphi-Quellcode:
rocedure SetProperty2(sProperty, sValue: string);
var
  LPropList: PPropList;
  LPropCount, I: Integer;
begin
  LPropCount := GetPropList(LBotOptions, LPropList);
  try
  for I := 0 to LPropCount-1 do
    begin
    if LPropList[I].Name = sProperty then
      begin
       ShowMessage(LPropList[I].Name);
       Break
      end;
    end;
  finally
    FreeMem(LPropList);
  end;
end;
Damit finde ich nun die richtige eigenschaft. Nun brauche ich noch den Weg wie ich die Eigenschaft schreibe???? Ich hangel mich hier von ast zu ast ... Wenn jemand dafür noch ein Weg hat wäre das super!

Eigentlich müsste das von oben funktionieren.

Noch ein Versuch:
Delphi-Quellcode:
procedure SetProperty3(ABotOptions : TBotOptions; sProperty, sValue: string);
var
  LPropList: PPropList;
  LPropCount, I: Integer;
begin
  LPropCount := GetPropList(ABotOptions, LPropList);
  try
  for I := 0 to LPropCount-1 do
    begin
    if LPropList[I].Name = sProperty then
      begin
       // Abhängig von Typ in LPropList[I].Kind
       case LPropList[I].Kind of
         tkString : SetStrProp(ABotOptions,LPropList[I].Name,sValue);
         tkInteger : SetInt64Prop(ABotOptions,LPropList[I].Name,StrToInt(sValue));
         tkEnumeration : SetOrdProp(ABotOptions,LPropList[I].Name,Ord(IfThen(LowerCase(sValue) = 'true',true,false)));
       end;
       Break;
      end;
    end;
  finally
    FreeMem(LPropList);
  end;
end;

ScharfeMietze 7. Okt 2018 18:08

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Heureka :twisted:
Delphi-Quellcode:
procedure SetProperty2(sProperty, sValue: string);
var
  LPropList: PPropList;
  LPropCount, I: Integer;
begin
  LPropCount := GetPropList(LBotOptions, LPropList);
  try
  for I := 0 to LPropCount-1 do
    begin
    if LPropList[I].Name = sProperty then
      begin
        SetStrProp(LBotOptions,LPropList[I].Name,sValue);
        Break;
      end;
    end;
  finally
    FreeMem(LPropList);
  end;
end;
funktioniert bei mir. Zusammen mit den Tips das es published sein muss und ein Object.


das
Delphi-Quellcode:
       case LPropList[I].Kind of
         tkString : SetStrProp(ABotOptions,LPropList[I].Name,sValue);
         tkInteger : SetInt64Prop(ABotOptions,LPropList[I].Name,StrToInt(sValue));
         tkEnumeration : SetOrdProp(ABotOptions,LPropList[I].Name,Ord(IfThen(LowerCase(sValue) = 'true',true,false)));
müsste ich doch weglassen können wenn ich weiß das Property von LBotOptions identisch ist mit dem sValue(string) .... oder übersehe ich da was?

Ansonsten schon mal Vielen lieben dank!! Das ist/war enorm hilfreich !!!!

Delphi.Narium 7. Okt 2018 18:34

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Wenn Du weißt, dass der zu setzende Typ mit dem zu setzenden Wert immer übereinstimmt, dann musst Du natürlich den Typen nicht mehr abfragen.

Sprich: Wenn SetProperty2 nur zum Setzen von String genutzt wird, kann das Case entfallen.

War halt davon ausgegangen, dass Du eine Routine suchst, bei der es egal ist, was da an Werten und Typen "reinkommt". Bekannt seien nur Eigenschaftsname und der zu setzende Wert.

Dazu wollte ich dann eine Routine haben, der es quasi egal ist, was da rein kommt. Sie sucht die entsprechende Eigenschaft und setzt dann typkonform deren Wert.

Trotzdem müsste meiner Meinung nach dashier reichen:
Delphi-Quellcode:
SetStrProp(LBotOptions,sProperty,sValue);
Die von Dir implementierte Schleife passiert im Inneren von SetStrProp noch einmal, da dort auch zuerst die Eigenschaft des Objektes gesucht wird, um dieser dann den Wert zuzuweisen.

Deine Schleife dient also nur zur Absicherung, dass vor dem Setzen geprüft wird, ob es die Eigenschaft gibt.

Das müsste auch in etwa so funktionieren:
Delphi-Quellcode:
if IsPublishedProp(LBotOptions,sProperty) then begin
  SetStrProp(LBotOptions,sProperty,sValue);
end;

Schokohase 7. Okt 2018 22:24

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Gibt es eigentlich einen Grund dafür warum du nicht einfach eine Klasse mit den passenden Eigenschaften deklarierst und dann mit Delphi-Referenz durchsuchenREST.Json.TJson.JsonToObject arbeitest?

Die GroupOptions würden z.B. in diese Klasse passen
Delphi-Quellcode:
uses
  REST.Json.Types;

TGroupOptionsData = class
private
  [JSONName( 'ChatID' )]
  FChatId:               string;
  [JSONName( 'DeleteSpam' )]
  FDeleteSpam:           Boolean;
  [JSONName( 'RestrictNewUser' )]
  FRestrictNewUser:      Boolean;
  [JSONName( 'AntiSpamMessage' )]
  FAntiSpamMessage:      string;
  [JSONName( 'can_send_messages' )]
  FCanSendMessages:      Boolean;
  [JSONName( 'can_send_media_messages' )]
  FCanSendMediaMessages: Boolean;
  [JSONName( 'can_send_other_messages' )]
  FCanSendOtherMessages: Boolean;
  [JSONName( 'can_add_web_page_previews' )]
  FCanAddWebPagePreviews: Boolean;
  [JSONName( 'Creator' )]
  FCreator:              string;
  [JSONName( 'blacklist' )]
  FBlacklist:            string;
  [JSONName( 'whitelist' )]
  FWhitelist:            string;
  [JSONName( 'restrict_time' )]
  FRestrictTime:         Integer;
  [JSONName( 'welcomemessage' )]
  FWelcomeMessage:       string;
  [JSONName( 'start' )]
  FStart:                Boolean;
public
  property ChatId: string read FChatId write FChatId;
  property DeleteSpam: Boolean read FDeleteSpam write FDeleteSpam;
  property RestrictNewUser: Boolean read FRestrictNewUser write FRestrictNewUser;
  property AntiSpamMessage: string read FAntiSpamMessage write FAntiSpamMessage;
  property CanSendMessages: Boolean read FCanSendMessages write FCanSendMessages;
  property CanSendMediaMessages: Boolean read FCanSendMediaMessages write FCanSendMediaMessages;
  property CanSendOtherMessages: Boolean read FCanSendOtherMessages write FCanSendOtherMessages;
  property CanAddWebPagePreviews: Boolean read FCanAddWebPagePreviews write FCanAddWebPagePreviews;
  property Creator: string read FCreator write FCreator;
  property Blacklist: string read FBlacklist write FBlacklist;
  property Whitelist: string read FWhitelist write FWhitelist;
  property RestrictTime: Integer read FRestrictTime write FRestrictTime;
  property WelcomeMessage: string read FWelcomeMessage write FWelcomeMessage;
  property Start: Boolean read FStart write FStart;
end;
und dann einfach
Delphi-Quellcode:
uses
  REST.Json;

const
  jsonstr =                                                 //
    ' {' + sLineBreak +                                     //
    '   "ChatID": "-xxxxxx",' + sLineBreak +                //
    '   "DeleteSpam": true,' + sLineBreak +                 //
    '   "RestrictNewUser": true,' + sLineBreak +            //
    '   "AntiSpamMessage": "SpamPost",' + sLineBreak +      //
    '   "can_send_messages": true,' + sLineBreak +          //
    '   "can_send_media_messages": false,' + sLineBreak +   //
    '   "can_send_other_messages": false,' + sLineBreak +   //
    '   "can_add_web_page_previews": false,' + sLineBreak + //
    '   "Creator": "blablub",' + sLineBreak +               //
    '   "blacklist": "blablub",' + sLineBreak +             //
    '   "whitelist": "",' + sLineBreak +                    //
    '   "restrict_time": 15,' + sLineBreak +                //
    '   "welcomemessage": "",' + sLineBreak +               //
    '   "start": true' + sLineBreak +                       //
    ' }';
var
  options: TGroupOptionsData;
begin
  options := TJson.JsonToObject<TGroupOptionsData>(jsonstr);
  try
    // ...
  finally
    options.Free;
  end;
end;

ScharfeMietze 7. Okt 2018 23:53

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
hpffffffffff Die Antwort ist simpel. Ich wusste nicht das es auch so geht ..:shock::-D


Vielen Dank! Werde ich bei Tageslicht ausprobieren ...
das ist natürlich extrem wenig code und damit sehr sympatisch. wenn es um json geht...
Extrem lehrreich der Tag für mich! Danke :)


Frage: Ist das case sensitive?


Ich habe ein weiteres Problem, das in meinem JsonString nicht nur 1 Objekt von dem Typ TBotOptions ist sondern beliebig viele... im Reader erstellt er mir immer am Anfang eines neuen Objektes LBotoptions und speichert es am ende in eine generische Liste.

Ich wüsste nicht wie ich das mit deiner Methode umsetze....

Schokohase 8. Okt 2018 05:15

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie
 
Schau dir mal https://jsontodelphi.com an.

Ein Nachteil ist allerdings, dass dort nicht mit dem
Delphi-Quellcode:
JSONName
Attribut gearbeitet wird (siehe mein Code).

Bei JSON sind die Eigenschaftsnamen case-sensitive bei Delphi nicht. Und dann passiert z.B. so etwas wie
Code:
{
  "foo": 1,
  "Foo": 2
}
Delphi-Quellcode:
unit RootUnit;

{*******************************************************************************
    Generated By  : JsonToDelphiClass - 0.65 
    Project link  : https://github.com/PKGeorgiev/Delphi-JsonToDelphiClass
    Generated On  : 2018-10-08 01:16:30

    Created By    : Petar Georgiev - (http://pgeorgiev.com)
    Adapted Web By : Marlon Nardi - (http://jsontodelphi.com)
*******************************************************************************}

interface

uses Generics.Collections, Rest.Json;

type

TRootClass = class
private
  FFoo: Extended;
  FFoo: Extended;
public
  property Foo: Extended read FFoo write FFoo;
  property foo: Extended read FFoo write FFoo;
  function ToJsonString: string;
  class function FromJsonString(AJsonString: string): TRootClass;
end;

implementation

{TRootClass}


function TRootClass.ToJsonString: string;
begin
  result := TJson.ObjectToJsonString(self);
end;

class function TRootClass.FromJsonString(AJsonString: string): TRootClass;
begin
  result := TJson.JsonToObject<TRootClass>(AJsonString)
end;

end.

ScharfeMietze 8. Okt 2018 08:28

AW: Gehen strings als Eigenschaftsnamen? Wenn ja wie?
 
Ja super vielen Dank :)
Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:14 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