【发布时间】:2011-08-17 11:52:31
【问题描述】:
分享这个问题的代码作为参考:Delphi TPair Exception
如何在不使用 TPair 且不从列表中提取/删除/删除该对的情况下从 TObjectDictionary 具体条目中检索键和值?
{$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);
//the code to look for a **concrete product** (ie: MyProduct1) goes here..
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
谢谢。
===========================
= 带有答案的代码 =
{$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;
MySearchedProduct: TProduct; // From Answer.
APair: TPair<TProduct, Integer>;
aProductName: 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);
Writeln('Enter the Product Name to search: ');
//the code to look for a **concrete product** goes here..
Readln(aProductName);
for MySearchedProduct in Mydict.Keys do
if (MySearchedProduct.Name = aProductName) then
break;
if MySearchedProduct.Name = aProductName then
WriteLn('I have found the product: ' + MySearchedProduct.Name)
else
WriteLn('I have not found a product with that name.');
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
【问题讨论】:
-
@RRUZ Gracias por la edición de la pregunta。感谢您对问题的编辑。我认为最好不要重复几乎相同的代码,但我认为最好在此处单独维护它。
-
两件事:(1)你忽略了编译器警告,不要那样做。如果字典不包含任何内容,则不会定义 for 循环变量 (
MySearchedProduct),从而导致 AV。 (2) 如果您需要按名称搜索产品,请使用TDictionary<string, Product>或TList<Product>。字典不应该用于顺序访问,而是用于基于键的快速搜索。如果您需要顺序访问,请使用TList<T>或TObjectList<T>。 -
@Cosmin-Prund 是的,我知道如果列表中没有任何内容,
MySearchedProduct将是nil。谢谢... 我不需要按名称搜索产品,这只是一个示例代码。我需要根据产品的任何属性、功能以及可能同时在其中的几个中搜索产品。因此,我需要完整的对象,因为搜索将超过可变数量的elements。感谢您的约会... :-)
标签: delphi generics vcl delphi-xe