![]() |
Eingeschränkte Generics (Bug?)
Hallo,
Habe ein kleines Problem mit den Generics. Weiß nicht ob folgendes ein Bug ist, oder ob ich was falsch mache:
Delphi-Quellcode:
Der Code funktioniert soweit.
type
// Ein Interface IIDObject = interface function GetID: Integer; end; // Testklasse, die dieses Interface Implementieren TTest = class(TInterfacedObject, IIDObject) function GetID: Integer; end; // Eine Objectlist, abgeleitet von TList<IIDObject> // und einem Generischen Parameter. // Die Items-Property soll jetzt überdeckt werden. TIDObjectList<T: IIDObject> = class(TList<IIDObject>) private function GetItem(Index: Integer): T; procedure SetItem(Index: Integer; const Value: T); public property Items[Index: Integer]: T read GetItem write SetItem; end; implementation { TIDObjectList<T> } function TIDObjectList<T>.GetItem(Index: Integer): T; begin Result := inherited Items[Index]; end; procedure TIDObjectList<T>.SetItem(Index: Integer; const Value: T); begin Items[Index] := Value; end; Wenn ich nun folgenden Code habe:
Delphi-Quellcode:
bekomme ich den Fehler:
procedure TForm1.Button1Click(Sender: TObject);
var tmp: TIDObjectList<TObject>; begin tmp := TIDObjectList<TObject>.Create; tmp.Free; end; Zitat:
ALLERDINGS:
Delphi-Quellcode:
erhalte ich hier auch einen Fehler:
procedure TForm1.Button1Click(Sender: TObject);
var tmp: TIDObjectList<TTest>; begin tmp := TIDObjectList<TTest>.Create; tmp.Free; end; Zitat:
An wem liegts? An Delphi oder an mir? PS: Ich benutze Delphi2009 Gruß Neutral General |
Re: Eingeschränkte Generics (Bug?)
Vermutlich wird hier nicht auf Object <> Interface verglichen und man muß ein Interface übergeben, wenn man es so in der Deklaration verlangt.
Selbst wenn das Objekt dieses Interface unterstützen würde. :gruebel: |
Re: Eingeschränkte Generics (Bug?)
Um das ganze noch etwas verwirrender zu machen.
Delphi-Quellcode:
Dann compiliert es :mrgreen:
// Wenn ich den ganzen Code so lasse wie er auch oben steht und die GetItem-Methode von so:
// (alt) function TIDObjectList<T>.GetItem(Index: Integer): T; begin Result := inherited Items[Index]; end; // auf so ändere // (neu) function TIDObjectList<T>.GetItem(Index: Integer): T; var tmp: T; begin Result := tmp; end; Wenn ich schreibe:
Delphi-Quellcode:
Dann gibts wieder den oben genannten Fehler. :wiejetzt:
function TIDObjectList<T>.GetItem(Index: Integer): T;
var tmp: T; begin tmp := inherited Items[Index]; Result := tmp; end; |
Re: Eingeschränkte Generics (Bug?)
Unter D2010 compiliert es, wenn ich folgendes schreibe:
Delphi-Quellcode:
Viele Grüße
TIDObjectList<T: IIDObject> = class(TList<T>)
|
Re: Eingeschränkte Generics (Bug?)
Zitat:
Ich hätte dann z.B. eine TTest1-Liste und eine TTest2-Liste. Sowohl TTest1 als auch TTest2 würden IIDObject implementieren. Eine normale TObjectList<TTest1> bzw. TObjectList<TTest2> kann ich nicht verwenden, weil die nicht zueinander kompatibel sind. (Keinen gemeinsamen Vorfahren bis auf TObject). Deswegen bin ich auf die Idee oben gekommen. Eine Liste die von einer TList<IIDObject> ableitet. Der Parameter der Funktion wäre dann vom Typ TList<IIDObject>. Ich könnte dann eine TIDObjectList<TTest1> und eine TIDObjectList<TTest2> übergeben. |
Re: Eingeschränkte Generics (Bug?)
Wenn ich nochmal überlege:
- du willst eine Liste, welche Interfaces (IIDObject oder Nachfahre) enthält - willst dann aber die Liste mit Objekten (welche zwar IIDObject unterstützt, aber selber kein Interface ist) erstellen. So kann das natürlich nicht gehn. Also wenn du die Liste nun mit dem Interface erstellst,
Delphi-Quellcode:
dann kannst du diesem nun Interfaces (IIDObject) oder Objekte (welche IIDObject unterstützen und bei Übergabe in das Interface umgewandelt werden) übergeben.
procedure TForm1.Button1Click(Sender: TObject);
var tmp: TIDObjectList<IIDObject>; begin tmp := TIDObjectList<IIDObject>.Create; tmp.Free; end; |
Re: Eingeschränkte Generics (Bug?)
Ja ich weiß. Also ich habe ja eine Interface-Liste. So oder so. Meine abgeleitete TIIDObjectList ist ja im Grunde auch eine Interface-Liste.
Allerdings kann ich bei einer TIDObjectList nur auf die Methoden der Objekte zugreifen, die vom Interface unterstützt werden. Das ist aber nicht gewollt. Deswegen der Typ-Parameter damit ich die Items-Property der Interface-Liste überschreiben/überdecken kann und intern die Interfaces quasi auf die Typ-Parameter-Klasse caste. |
Re: Eingeschränkte Generics (Bug?)
[info]
irgendwie war des DPs Codeformatter futsch - hier war grade keine Codeformatierung zu sehn - und alles zwischen < und > wurde ebenfalls nicht angezeigt (falls sich grad wer über meinen Code-Abschnitt in #6 wunderte) |
Re: Eingeschränkte Generics (Bug?)
Hallo,
Wollte mich mal melden um Bescheid zu sagen, dass ichs geschafft habe. Zuerst habe ich statt des Interfaces eine abstrakte Klasse genommen. Problem war dann aber immernoch:
Delphi-Quellcode:
Hier wurde dann im konkreten Fall einem TTest ein TIDObject (entspricht IIDObject) zugewiesen. Was natürlich nicht geht und der blöde (= schlaue) Compiler leider gemerkt hat. Casten a la:
function TIDObjectList<T>.GetItem(Index: Integer): T;
begin Result := inherited Items[Index]; end;
Delphi-Quellcode:
funktioniert mit diesen generischen Dingern leider nicht. Dann habe ich.. sagen wir.. manuell gecastet :stupid:
Result := T(inherited Items[Index]);
Delphi-Quellcode:
Und jetzt funktioniert es :mrgreen:
function TIDObjectList<T>.GetItem(Index: Integer): T;
var tmp: Pointer; begin tmp := inherited Items[Index]; Move(tmp,Result,SizeOf(Pointer)); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:25 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