![]() |
Delphi-Version: 5
Begrenzter String, TList und InterfaceObject > Datenmüll
Hallo,
Beim Umstieg von Delphi XE auf XE8 bin ich auf folgendes Problem gestoßen: Vorgeschichte: Ich verwende einen auf 10 Zeichen begrenzten String als "ID". Diesen kann ich ohne Probleme als Typ einer TList verwenden:
Delphi-Quellcode:
In einem TInterfacedObject verwende ich nun TList als Member:
type
MyID = String[10]; // ... var ID1, ID2 : MyID; Liste : TList<MyID>; begin ID1 := ('ABCDEFGHIJ'); Liste := (TList<MyID>.Create); Liste.Add(ID1); ID2 := (Liste[0]); end;
Delphi-Quellcode:
Problem:
IMyObject<T> = interface
['{22041332-1221-4EBD-BBC5-1AF3C914E08B}'] procedure AddValue(const Value : T); function GetValue(const Index : Integer) : T; end; TMyObject<T> = class(TInterfacedObject, IMyObject<T>) strict private internalList : TList<T>; public constructor Create; procedure AddValue(const Value : T); function GetValue(const Index : Integer) : T; end; // ... constructor TMyObject<T>.Create; begin internList := (TList<T>.Create); end; procedure TMyObject<T>.AddValue(const Value : T); begin internList.Add(Value); end; function TMyObject<T>.GetValue(const Index : Integer) : T; begin Result := (internList[Index]); end; Wenn ich ein Objekt vom Typ IMyObject<MyID> erzeuge und via AddValue eine MyID hinzufüge entsteht Datenmüll:
Delphi-Quellcode:
Wert von ID2: 'ABC'#$90'!'#$B#2#$8D'þ'#$18
var
ID1, ID2 : MyID; MyObj1 : IMyObject<MyID>; begin ID1 := ('ABCDEFGHIJ'); MyObj1 := (TMyObject<MyID>.Create); MyObj1.AddValue(ID1); ID2 := (MyObj1.GetValue(0)); end; Die erste 3 Zeichen sind noch korrekt, der Rest jedoch nicht. Es sieht so aus, als wenn er nicht genügend Speicher für den String reserviert. MyID ist ein zentraler Bestandteil der Software. Wodurch tritt das Problem auf und wie könnte man es lösen? Vielen Dank im Voraus |
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
XE8 oder XE8.1?
Die Generics - speziell die Listen - sind bei XE8 komplett umgestellt worden und es gibt dort einen Bug speziell mit Records - der aber auch diesen
Delphi-Quellcode:
Typen betrifft. Behoben wurde dieser Bug mit XE8.1
String[10]
![]() ![]() |
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Hallo,
Ich verwende "22.0.19908.869" (XE8 Subscription Update 1). UPDATE: Mit dem inoffiziellen Fix ( ![]() BTW: Vielen Dank für die Links. |
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Jupp, da scheint noch ein Bug zu sein ...
Mit DX10 funktioniert das auf jeden Fall |
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Zitat:
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Wenn der Bug in Seattle gelöst wurde, müsste er demnächst auch in XE8 (Subscription Update 2 o.ä.) gefixt werden, wurde ja für demnächst angekündigt.
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Zitat:
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Kann einer bitte die Units "System.Generics.Collections" und "System.Generics.Defaults" von Delphi XE7 posten?
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Zitat:
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Das dürfte nicht erlaubt sein. Diese würden mit großer Wahrscheinlichkeit auch nicht so einfach unter XE8 funktionieren.
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Zitat:
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Schreib doch mal MEissing an und frage nach einer schnellen Lösung.
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Es gibt aber Abhilfe
Delphi-Quellcode:
program dp_186522;
{$APPTYPE CONSOLE} {$R *.res} uses System.Generics.Collections, System.SysUtils; type TMyID = string[ 10 ]; IMyObject<T> = interface [ '{22041332-1221-4EBD-BBC5-1AF3C914E08B}' ] procedure AddValue( const Value: T ); function GetValue( const Index: Integer ): T; end; TMyObject<T> = class( TInterfacedObject, IMyObject<T> ) strict private internalList: TList<T>; public constructor Create; destructor Destroy; override; procedure AddValue( const Value: T ); function GetValue( const Index: Integer ): T; end; TWrap<T> = record private FValue: T; public class operator implicit( const a: T ): TWrap<T>; class operator implicit( const a: TWrap<T> ): T; end; TMyWrappedObject<T> = class( TInterfacedObject, IMyObject<T> ) strict private internalList: TList<TWrap<T>>; public constructor Create; destructor Destroy; override; procedure AddValue( const Value: T ); function GetValue( const Index: Integer ): T; end; { TMyObject<T> } procedure TMyObject<T>.AddValue( const Value: T ); begin internalList.Add( Value ); end; constructor TMyObject<T>.Create; begin inherited; internalList := TList<T>.Create; end; destructor TMyObject<T>.Destroy; begin internalList.Free; inherited; end; function TMyObject<T>.GetValue( const Index: Integer ): T; begin Result := internalList[ index ]; end; { TWrap<T> } class operator TWrap<T>.implicit( const a: T ): TWrap<T>; begin Result.FValue := a; end; class operator TWrap<T>.implicit( const a: TWrap<T> ): T; begin Result := a.FValue; end; { TMyWrappedObject<T> } procedure TMyWrappedObject<T>.AddValue( const Value: T ); begin internalList.Add( Value ); end; constructor TMyWrappedObject<T>.Create; begin inherited; internalList := TList < TWrap < T >>.Create; end; destructor TMyWrappedObject<T>.Destroy; begin internalList.Free; inherited; end; function TMyWrappedObject<T>.GetValue( const Index: Integer ): T; begin Result := internalList[ index ]; end; procedure Test1; var ID1, ID2: TMyID; Liste : TList<TMyID>; begin ID1 := ( 'ABCDEFGHIJ' ); Liste := ( TList<TMyID>.Create ); Liste.Add( ID1 ); ID2 := ( Liste[ 0 ] ); Assert( ID1 = ID2 ); end; procedure Test2; var ID1, ID2: TMyID; MyObj1 : IMyObject<TMyID>; begin ID1 := ( 'ABCDEFGHIJ' ); MyObj1 := ( TMyObject<TMyID>.Create ); MyObj1.AddValue( ID1 ); ID2 := ( MyObj1.GetValue( 0 ) ); Assert( ID1 = ID2 ); end; procedure Test3; var ID1, ID2: TMyID; MyObj1 : IMyObject<TMyID>; begin ID1 := ( 'ABCDEFGHIJ' ); MyObj1 := ( TMyWrappedObject<TMyID>.Create ); MyObj1.AddValue( ID1 ); ID2 := ( MyObj1.GetValue( 0 ) ); Assert( ID1 = ID2 ); end; begin try Test1; Test2; // fails Test3; // pass except on E: Exception do Writeln( E.ClassName, ': ', E.Message ); end; Readln; end. |
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Zitat:
|
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Nein, ist nur verschlüsselt im Setup enthalten. (natürlich installieren mit der XE7-Lizenz)
In VM/Sandbox installieren? |
AW: Begrenzter String, TList und InterfaceObject > Datenmüll
Ich danke euch allen für die Antworten und Abhilfe.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 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