fer*_*ega 5 delphi generics exception delphi-xe
我有这个高峰来测试TPair.您可以在新的Delphi XE Console-app上复制+粘贴.我用例外标记了这一行:
项目Project1.exe引发异常类EAccessViolation,并在模块'Project1.exe'中显示消息'地址为0045042D的访问冲突'.读取地址A9032D0C.
任何的想法 ?
谢谢.
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Generics.Defaults,
Generics.Collections;
type
TProduct = class
private
FName: string;
procedure SetName(const Value: string);
published
public
property Name: string read FName write SetName;
end;
type
TListOfProducts = TObjectDictionary<TProduct, Integer>;
{ TProduct }
procedure TProduct.SetName(const Value: string);
begin
FName := Value;
end;
var
MyDict: TListOfProducts;
MyProduct1: TProduct;
MyProduct2: TProduct;
MyProduct3: TProduct;
APair: TPair<TProduct, Integer>;
aKey: string;
begin
try
MyDict := TListOfProducts.Create([doOwnsKeys]);
MyProduct1 := TProduct.Create;
MyProduct1.Name := 'P1';
MyProduct2 := TProduct.Create;
MyProduct2.Name := 'P2';
MyProduct3 := TProduct.Create;
MyProduct3.Name := 'P3';
MyDict.Add(MyProduct1, 1);
MyDict.Add(MyProduct2, 2);
MyDict.Add(MyProduct3, 3);
APair := MyDict.ExtractPair(MyProduct1);
Writeln(APair.Key.Name); // <--- Error is Here.
Writeln(IntToStr(APair.Value));
Readln(aKey);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Run Code Online (Sandbox Code Playgroud)
Dav*_*nan 11
这是一个Delphi错误. TDictionary<TKey,TValue>.ExtractPair不分配Result.
代码如下:
function TDictionary<TKey,TValue>.ExtractPair(const Key: TKey): TPair<TKey,TValue>;
var
hc, index: Integer;
begin
hc := Hash(Key);
index := GetBucketIndex(Key, hc);
if index < 0 then
Exit(TPair<TKey,TValue>.Create(Key, Default(TValue)));
DoRemove(Key, hc, cnExtracted);
end;
Run Code Online (Sandbox Code Playgroud)
Result应在拨打电话时分配DoRemove.
解决这个bug很难. ExtractPair是在不破坏密钥的情况下从字典中获取项目的唯一方法,因此您必须调用它.但由于它不会返回提取的项目,因此您需要先读取该项目,记住该值,然后调用ExtractPair.