AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Assign für TDictionary implementieren

Ein Thema von DCoderHH · begonnen am 4. Sep 2019 · letzter Beitrag vom 4. Sep 2019
Antwort Antwort
Seite 1 von 2  1 2   
DCoderHH

Registriert seit: 4. Feb 2015
Ort: Hamburg
84 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Assign für TDictionary implementieren

  Alt 4. Sep 2019, 11:43
Hallo,

ich hab eine eigene Klasse (TMyDictionary), die von TDictionary abgeleitet ist erstellt. Diese soll u.a. auch eine Assign-Funktion erhalten, um das ganze Dictionary in ein anderes zu kopieren. Doch es gibt in der Zeile, die mit **FEHLER** markiert ist, diesen Fehler:

Code:
Fehler E2010 Inkompatible Typen 'MeineUnit.TValue' und 'System.Rtti.TValue'
Was kann ich tun?
(Warum klappt das Zuweisen von TKey? Das von TValue auf die gleiche Art und weise aber nicht?)

Delphi-Quellcode:
interface

TMyDictionary<TKey, TValue> = class(TDictionary<TKey, TValue>)
public
  ...
  procedure Assign(Source: TObject); virtual;
end;

...

implementation

procedure TMyDictionary<TKey, TValue>.Assign(Source: TObject);
var
  LKey: TKey;
  LValue: TValue;
begin
  if Source is TMyDictionary<TKey, TValue> then
  begin
    for LKey in (Source as TMyDictionary<TKey, TValue>).Keys do
    begin
      LValue := (Source as TMyDictionary<TKey, TValue>).Items[LKey];
      Add(LKey, LValue); <-- **FEHLER**
    end;
  end
  else
    AssignError(Source, self);
end;
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
7.174 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 11:56
Zeig mal die zugehörigen Uses-Anweisungen. TValue ist sowohl als generischer Typ in TDictionary als auch als relater Typ in System.RTTI deklariert. Eventuell hilft es die uses-Anwwisung etwas umzubauen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 12:08
Unabhängig vom Compilefehler: Die Signatur von Assign ist Unfug - den Source Parameter als TObject zu deklarieren ist unnötig, sowas macht nur Sinn, wenn man eine Abstrakte Basisklasse hat, wie bei TPersistent der Fall, wo erst die Ableitungen dann entscheiden, was sie annehmen - beim generischen Dictionary wohl kaum der Fall.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
DCoderHH

Registriert seit: 4. Feb 2015
Ort: Hamburg
84 Beiträge
 
Delphi 10 Seattle Professional
 
#4

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 12:11
Unabhängig vom Compilefehler: Die Signatur von Assign ist Unfug - den Source Parameter als TObject zu deklarieren ist unnötig, sowas macht nur Sinn, wenn man eine Abstrakte Basisklasse hat, wie bei TPersistent der Fall, wo erst die Ableitungen dann entscheiden, was sie annehmen - beim generischen Dictionary wohl kaum der Fall.
Auch hier macht der Source Parameter als TObject Sinn, wenn man nicht nur TDictionarys zuweisen möchte...
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.022 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#5

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 12:37
Unabhängig vom Compilefehler: Die Signatur von Assign ist Unfug - den Source Parameter als TObject zu deklarieren ist unnötig, sowas macht nur Sinn, wenn man eine Abstrakte Basisklasse hat, wie bei TPersistent der Fall, wo erst die Ableitungen dann entscheiden, was sie annehmen - beim generischen Dictionary wohl kaum der Fall.
Auch hier macht der Source Parameter als TObject Sinn, wenn man nicht nur TDictionarys zuweisen möchte...
Aber du prüfst ja direkt, ob es TMyDictionary ist.

if Source is TMyDictionary<TKey, TValue> then

Wenn du irgend etwas anders übergibst, dann erscheint auf jeden Fall ein Fehler.

Dann lieber als Source-Parameter direkt den Type TMyDictionary verwenden. Dann fällt der Fehler direkt beim Compilieren auf.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
7.174 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 12:39
Aber du prüfst ja direkt, ob es TMyDictionary ist.
Das könnte in einer Ableitung aber ja durchaus anders sein.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.022 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#7

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 12:46
Aber du prüfst ja direkt, ob es TMyDictionary ist.
Das könnte in einer Ableitung aber ja durchaus anders sein.
Dann dürfte in der Ableitung aber kein Inherited aufgerufen werden, da ja sofort AssignError ins Spiel kommt.

Wenn es ein ganz anderer Parameter ist, der auch das Assign vom Elternobjekt nicht verwenden darf, dann könnte man auch ein "overload" verwenden.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#8

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 12:56
@bernau wie inherited darf nicht aufgerufen werden ...
Delphi-Quellcode:
procedure TMyOtherDict.Assign(Source:TObject);
begin
  if Source is TFoo then
  begin
    ...
  end
  else
    inherited;
end;
klar, nicht einfach blind aufrufen, aber durchaus konditional aufrufbar
  Mit Zitat antworten Zitat
DCoderHH

Registriert seit: 4. Feb 2015
Ort: Hamburg
84 Beiträge
 
Delphi 10 Seattle Professional
 
#9

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 13:06
Zeig mal die zugehörigen Uses-Anweisungen. TValue ist sowohl als generischer Typ in TDictionary als auch als relater Typ in System.RTTI deklariert. Eventuell hilft es die uses-Anwwisung etwas umzubauen.
Ich hab mal alles aus der Unit gelöscht, bis das hier übrig blieb (uses Rtti in Verbindung mit TValue in Foo verursacht das Problem):

Delphi-Quellcode:
unit MyUnit;

interface

uses
 Classes, generics.defaults, generics.Collections;

type
  TTest = class(TObject)
    procedure foo;
  end;

  TMyDictionary<TKey, TValue> = class(TDictionary<TKey, TValue>)
  public
    procedure Assign(Source: TObject); virtual;
  end;

implementation

uses
  Rtti;

procedure TTest.foo;
var
  V: TValue; <-- hier kommt das TValue aus der Rtti und muss es auch!
begin
end;

procedure TMyDictionary<TKey, TValue>.Assign(Source: TObject);
var
  LKey: TKey;
  LValue: TValue;
begin
  if Source is TMyDictionary<TKey, TValue> then
  begin
    for LKey in (Source as TMyDictionary<TKey, TValue>).Keys do
    begin
      LValue := (Source as TMyDictionary<TKey, TValue>).Items[LKey];
      Add(LKey, LValue); <-- **FEHLER**
    end;
  end
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Assign für TDictionary implementieren

  Alt 4. Sep 2019, 13:14
Der Scope auf Rtti.TValue ist näher als der auf den generischen Typparameter TValue. Also entweder umbenennen oder Rtti in das Interface uses verschieben. Diese Problematik hab ich auch schon of genug in meinem Dictionary Code gehabt.

Edit: Habs mal getestet, verschieben der unit bringt nichts. Ich würde die Klasse die das Rtti.TValue benutzt in eine andere Unit verfrachten, so dass sie nicht kollidieren - oder den generischen parameter umnennen, ich hab das mal so gelöst gehabt: map<tkey,t>

Übrigens die Schleife über die Keys und dann das Lookup jedes Wertes ist denkbar inperformant. Dann doch lieber direkt mit einer TPair<TKey,TValue> variable per for in über das Dictionary.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 4. Sep 2019 um 13:19 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

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