德尔福TPair异常 [英] Delphi TPair Exception
问题描述
项目Project1.exe引发异常
类EAccessViolation消息
'访问冲突在模块'Project1.exe'中的地址0045042D
。阅读
地址A9032D0C。
任何想法?
谢谢。
程序Project1;
{$ APPTYPE CONSOLE}
使用
SysUtils,
Genericics.Defaults,
泛型。
type
TProduct = class
private
FName:string;
procedure SetName(const Value:string);
发布
public
属性名称:string read FName write SetName;
结束
type
TListOfProducts = TObjectDictionary< TProduct,Integer> ;;
{TProduct}
程序TProduct.SetName(const Value:string);
begin
FName:= Value;
结束
var
MyDict:TListOfProducts;
MyProduct1:TProduct;
MyProduct2:TProduct;
MyProduct3:TProduct;
APair:TPair 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); //< ---错误在这里。
Writeln(IntToStr(APair.Value));
Readln(aKey);
除了
在E:Exception do
Writeln(E.ClassName,':',E.Message);
结束
结束。
这是一个Delphi错误。 TDictionary< TKey,TValue> .ExtractPair
不分配结果
。
RRUZ位于 QC中的错误。
代码如下:
function TDictionary< TKey,TValue> .ExtractPair(const关键:TKey):TPair var
hc,index:Integer;
begin
hc:=哈希(键);
index:= GetBucketIndex(Key,hc);
如果index< 0然后
退出(TPair< TKey,TValue>。创建(键,默认(TValue)));
DoRemove(Key,hc,cnExtracted);
结束
结果
DoRemove
。
很难解决这个错误。 ExtractPair
是将项目从字典中取出而不会破坏该键的唯一方式,因此您必须调用它。但是由于它不会返回提取的项目,您需要先阅读该项目,记住该值,然后调用 ExtractPair
。
I have this spike to test TPair. You can copy+paste on a new Delphi XE Console-app. I have marked the line with the exception:
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 0045042D in module 'Project1.exe'. Read of address A9032D0C.
Any Idea ?
Thanks.
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.
This is a Delphi bug. TDictionary<TKey,TValue>.ExtractPair
does not assign Result
.
RRUZ located the bug in QC.
The code reads:
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;
Result
should be assigned when the call to DoRemove
is made.
It's quite hard to work around this bug. ExtractPair
is the only way to get an item out of the dictionary without destroying the key and so you have to call it. But since it won't return the extracted item, you need to first read the item, remember the value, and then call ExtractPair
.
这篇关于德尔福TPair异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!