德尔福TPair例外

fer*_*ega 5 delphi generics exception delphi-xe

我有这个高峰来测试TPair.您可以在新的Delphi XE Con​​sole-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.

RRUZ找到了QC中错误.

代码如下:

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.

  • @RRUZ我没有看到一次性例程的问题.特别是当我们调试VCL时.你是否同意我的看法,这是VCL代码中的一个简单的错误? (3认同)
  • @ A.Bouchez确实.让我觉得另一件事就是将bug报告给QC,然后他们制作了另一个保留bug的主要版本.这种情况经常发生. (3认同)
  • @Rruz,美国法律允许复制受版权保护作品的有限部分,以便进行审查和批评等.它被称为*合理使用*.我相信大卫的答案符合标准. (2认同)
  • @RRUZ那个QC报告确实是同一个bug.令人非常失望的是QC系统不会导致这些明显的错误被修复.请记住,这是16个月前报道的! (2认同)