AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Generics: Ungültige Typumwandlung

Ein Thema von Codewalker · begonnen am 12. Nov 2012 · letzter Beitrag vom 12. Nov 2012
Antwort Antwort
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#1

Generics: Ungültige Typumwandlung

  Alt 12. Nov 2012, 11:15
Delphi-Version: XE2
Hallo zusammen.

Mir machen mal wieder die Generics Kopfschmerzen. Ich möchte in einer Settings-Klasse eine generische get-Funktion haben, die mir den gewünschten Typ direkt castet. Das ganze sollte meiner Meinung nach so aussehen:

Delphi-Quellcode:

// Nur als Hinweis:
FValues = TDictionary<string, Variant>;

{ ...}

function TSettings.GetItem<T>(Key: String): T;
begin
  Result := T(FValues[Key]);
end;
Das ganze wollte ich dann z.B. so aufrufen:

Delphi-Quellcode:
var
 a: TMeineKlasse;
 i: Integer;
begin
 a := Settings.GetItem<TMeineKlase>('blabla');
 i := Settings.GetItem<Integer>('neZahl');
 // usw.
Leider bekomme ich als Fehler:
Code:
Ungültige Typumwandlung
bei meinem cast. Warum geht das nicht und was müsste ich denn ändern?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

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

AW: Generics: Ungültige Typumwandlung

  Alt 12. Nov 2012, 12:18
Das hat nichts mit den Genercis zu tun sondern damit das du einen Variant versuchst auf eine Objektinstanz zu casten.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
3.683 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Generics: Ungültige Typumwandlung

  Alt 12. Nov 2012, 12:41
Das hat nichts mit den Genercis zu tun sondern damit das du einen Variant versuchst auf eine Objektinstanz zu casten.
Hat sehr wohl mit Generics zu tun, dass er einen Variant auf T zu hardcasten versucht.

In deinem Fall solltest du zu Rtti.TValue greifen. Das ist der Container, der alles aufnehmen kann, was es so gibt (und nein, Variant kann das nicht).

Delphi-Quellcode:
FValues = TDictionary<string, TValue>;

function TSettings.GetItem<T>(Key: string): T;
begin
  Result := FValues[Key].AsType<T>;
end;
Ein Wort der Warnung an dieser Stelle: Im Gegensatz zu Variant, bei welchem einige implizite Typenkonvertierungen durchgeführt werden, wirft TValue.AsType<T> eine EInvalidCast Exception, wenn das was drin steht, nicht direkt zuweisungskompatibel zu T ist.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Generics: Ungültige Typumwandlung

  Alt 12. Nov 2012, 14:44
Das mit TValue kannte ich noch nicht. Das klingt deutlich sinniger als Variant. Ich werde das versuchen, danke
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Generics: Ungültige Typumwandlung

  Alt 12. Nov 2012, 15:15
Okay, sieht für die Abfrage ganz gut aus. Aber ich darf jetzt keine Werte mehr in das Dictionary einfüllen

Data.Add('key', IrgendeinVariant);
Code:
[DCC Fehler] DataQueries.pas(56): E2010 Inkompatible Typen: 'TValue' und 'Variant'
Edit: Habs gefunden.

Data.Add('key', TValue.From<Variant>(Inhalt)); Quelle: http://stackoverflow.com/questions/2...-to-store-data

Geändert von Codewalker (12. Nov 2012 um 15:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
3.683 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Generics: Ungültige Typumwandlung

  Alt 12. Nov 2012, 16:22
Andere Möglichkeit wäre, TValue.FromVariant zu benutzen, dann wird nämlich der Datentyp benutzt, der intern im Variant steckt.

Vorteil: Wenn du im Variant nen string stehen hast, wird nicht der Variant, in dem der string steht im TValue gespeichert, sondern der string.
Nachteil: Wie im vorherigen Post erwähnt, geht dir eventuell notwendige implizite Typenkonvertierung verloren

Generell kann ich empfehlen, auf Variants zu verzichten, sofern du einen generischen Ansatz verfolgst. Benutze an Stellen, wo du zur Compiletime den Type nicht kennst, lieber TValue, um Werte auszutauschen. An allen anderen Stellen, benutze den konkreten Datentyp. TValue verfügt für die meisten Standardtypen über überladene Implicit Operatoren, die dir den Aufruf von z.B. TValue.From<Integer>(i) ersparen.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (12. Nov 2012 um 16:27 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 11:34 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf