AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Getter wird übergangen

Ein Thema von Medium · begonnen am 17. Jun 2010 · letzter Beitrag vom 18. Jun 2010
Antwort Antwort
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#1

AW: Getter wird übergangen

  Alt 17. Jun 2010, 18:19
Dann kann es sein, daß der Compiler, Aufgrund deiner komischen Sichtbarkeitsreglungen, durchdreht.
Dein TDBUser ist als Private deklariert, aber du willst es in Public verwenden, als Result für eine Public-Methode/Property.
So komisch sind die eigentlich garnicht. In C# hab ich solche Konstrukte schon haufenweise verwendet. Ohne Probleme.

Ich habe aber testweise die TDBUsers als ganz eigenständige Klasse gesetzt, was leider noch immer nichts an dem Problem geändert hat. GetDBUserByLogin() wird noch immer geflissentlich gemieden, obwohl explizit auf die zugehörige Property lesend zugegriffen wird . Daran lag es leider nicht. (Was heisst leider... das wäre recht dümmlich, wenn sowas nicht in Delphi ginge )


EDIT: Okay, lustig...
Ich habe noch eine weitere Property "Users", die wie "UsersByLogin" arbeitet, aber eben eine ID statt eines Logins nimmt:
Delphi-Quellcode:
  TDB = class
  private
    class var FQuery: TUniQuery;
    class var FUser: TDBUser;
    class function GetDBUser(aUserID: Integer): TDBUser; static;
    class function GetDBUserByLogin(aLogin: string): TDBUser; static;
  public
    class property Users[aUserID: Integer]: TDBUser read GetDBUser;
    class property UsersByLogin[aLogin: string]: TDBUser read GetDBUserByLogin;
  end;

implementation

class function TDB.GetDBUser(aUserID: Integer): TDBUser;
begin
  FUser.FID := aUserID;
  result := FUser;
end;

Folgenden Methode:
Delphi-Quellcode:
procedure TframeUsers.btnResetPasswordClick(Sender: TObject);
var
  id: Integer;
begin
  id := qryUsers.FieldByName('id').AsInteger; // <---- !!!
  TDB.Users[id].Password := '';
end;
Hier wird mir vom Compiler gemeldet, dass der auf "id" zugewiesene Wert nicht mehr verwendet wird!
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (17. Jun 2010 um 18:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

Registriert seit: 5. Mai 2008
940 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Getter wird übergangen

  Alt 17. Jun 2010, 18:29
So komisch sind die eigentlich garnicht. In C# hab ich solche Konstrukte schon haufenweise verwendet. Ohne Probleme.
Welche VS-Version hast du? Also 2010 lässt es ganz sicher nicht zu, dass man in einer Public-Methode einen Private-Typ zurückliefert. Hab ich selber schon mehrmals versucht.

Ist ja auch total sinnlos. So verhinderst du ja, dass man den Rückgabewert in einer Variable speichern kann... Wat'n Schwachsinn...
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: Getter wird übergangen

  Alt 17. Jun 2010, 18:36
@implementation:
#Develop. Und das mit dem Schwachsinn will ich mal dahin gestellt sein lassen. Es gibt hier schon einen triftigen Grund dafür, dass die Referenz selbst nicht gepeichert werden soll. Immerhin ist die gesamte Klasse quasi abstrakt - es werden ja gar keine Instanzen erzeugt.

Was ich damit schlicht erreichen will ist, dass man im eigentlichen Programm nachher die angenehme Schreibweise hat, ála:
TDB.Users[id].Name
TDB.Rights[id].Description
usw., und zwar je nach Feld nur lesend, oder auch schreibend. Dabei ist es ebenfalls wichtig, dass IMMER live aus der DB gelesen wird. Was will ich dann jemals mit einer Instanz von TDB.Users[id] sinnvoll anfangen wollen!?

@himi:
Ich bastels mal um. Edit: Leider kein Effekt. Die Properties sind in der eigentlichen (etwas größeren) Klasse auch nicht allein:
Delphi-Quellcode:
  public
    class function AddUser(aName, aSurname, aLogin, aPassword: string): Integer;
    class function UserExists(aUserID: Integer): Boolean; overload;
    class function UserExists(aLogin: string): Boolean; overload;
    class property Query: TUniQuery read FQuery write FQuery;
    class property Users[aUserID: Integer]: TDBUser read GetDBUser;
    class property UsersByLogin[aLogin: string]: TDBUser read GetDBUserByLogin;
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (17. Jun 2010 um 18:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

AW: Getter wird übergangen

  Alt 17. Jun 2010, 18:54
Das Problem mit den ganzen Class-Methoden ist das es nicht Threadsicher ist.
Wenn ein mehrere Threads gleichzeitig die Klasse verwenden kommen ganz "tolle" Ergebnisse dabei raus.
Was spricht dagegen eine ganze normale Klasse daraus zu machen und dann, wenn es unbedingt sein muss, eine "globale" Instanzvariable zu nutzen? Dann kannst du diese Bei Programmstart initialisieren und bei Programm Ende freigeben und wirst keine Probleme haben wenn mal mehrere Threads die Klasse zum gleichen Zeitpunkt verwenden.

Es geht also nicht darum alle Klassenmethoden zu entfernen sondern nur zu verhindern das Variablen von mehreren Threads gleichzeitig genutzt werden.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#5

AW: Getter wird übergangen

  Alt 17. Jun 2010, 19:03
Hm, mal abgesehen davon, dass im gesamten Projekt bisher keine Verwendung von Threads vorgesehen ist, ließe sich im Zweifel das Zuweisen der FID und die Rückgabe der Klassenreferenz noch in eine Critical Section stopfen. Das Problem wäre mit einer globalen Instanzvariablen auch das selbe: Es würde die ID von einem Thread gesetzt, und er könnte sich schon nicht mehr sicher sein, dass sie von einem anderen nicht umgehend geändert wurde, noch bevor die 2 Dereferenzierungen bis zum gewünschten Ergebnis ausgeführt sind.
Oder meintest du die TDB-Klasse, nicht die Sub-Klassen*? Da könnte eine Instanz pro Thread noch Sinn machen, ich müsste mir dann nur grad überlegen ob und wo ich diese dann hin schmeissen will. Eigentlich wollte ich den Zugriff von überall im Programm möglich machen, ohne je etwas dafür Createn zu müssen.
*) Da wäre dann die Frage, ob jede TDB-Instanz eine ganz eigene TDBUser-Klassenreferenz hat, und nicht nachher mehrere TDBs auf die selbe TDBUser-Klasse zugreifen.

Da das hier offenbar alles zu nichts führt, frage ich einfach mal anders:
Wie würdet IHR es angehen, eine DB im Programm wie eine Collection aussehen zu lassen, die sämtliche Abfragen live aus der DB tätigt, und Zuweisungen auch umgehend in diese zurück speichert? Und zwar so, dass ich mir bei der Verwendung keinerlei Gedanken um Freigaben o.ä. machen muss.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (17. Jun 2010 um 19:08 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#6

AW: Getter wird übergangen

  Alt 18. Jun 2010, 11:13
Update: Wenn ich die inneren Klassen zu Records (mit normalen Methoden natürlich, aber nach wie vor private) mache, aber ansonsten nichts zur ersten Version ändere, DANN funktioniert das ganze! Ich würde das daher durchaus als tatsächlichen Bug bezeichnen, und da soweit keine weiteren Vorschläge zum grundsätzlichen Vorgehen kamen, bzw. ich mit dem hier eigentlich recht zufireden bin, kann ich das Thema denke ich als gelöst betrachten.
Edit: Und das sollte auch die Problematik mit der Threadsicherheit eliminieren, da ja jetzt immer ein neuer Record geliefert werden dürfte.

Nochmals vielen Dank an alle!
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

AW: Getter wird übergangen

  Alt 18. Jun 2010, 12:27
genau, damit sollte es auch Threadsicher sein.
Ich hatte das Global in Anführungszeichen gepackt weil ich nicht wirklich global meinte sondern global innerhalb einer Threadklasse, innerhalb deiner Klasse die das handelt etc. so das aber keiner von außen drauf zugreifen kann. Aber durch den Umstieg auf Records hat sich das erübrigt.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.398 Beiträge
 
Delphi 12 Athens
 
#8

AW: Getter wird übergangen

  Alt 17. Jun 2010, 18:31
Eventuell schlägt sich auch hier wieder ein Fehler im Compiler nieder?

Versuch es mal so:
Delphi-Quellcode:
TDB = class
public
  type
    TDBUser = record
    private
      FID: Integer;
      // für jedes DB feld eben...
    public
      property ID: Integer read FID;
      property Name: string read FName;
    end;
private
  class var FQuery: TUniQuery;
  class var FUser: TDBUser;
  class function GetDBUserByLogin(aLogin: string): TDBUser; static;
public
  abc: Integer; // dummies
  xyz: String; //
  class property UsersByLogin[aLogin: string]: TDBUser read GetDBUserByLogin;
end;
Ansonsten wüßte ich auch nicht weiter (jedenfalls nicht ohne mal ein Testprojekt zum Testen zu haben).
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:08 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