显然你只想要一个单行,所以我试了一下,实现了一个TDictHelper允许使用单行创建和填充字典的。
使用任何形式的单行初始化 Dictionary 的问题在于它需要成对的值,而我们没有传递这些对所需的漂亮语法。例如,如果需要为TPair<Key, Value>.Create(A, B)添加到字典的每一对值使用语法,那将是一个丑陋的单行。
我确实想出了几个好看的替代品;第一个是这样使用的:
with TDictHelper<Integer, string> do
Dict := Make([P(1, 'one'), P(2, 'two')]);
Run Code Online (Sandbox Code Playgroud)
使用with是必需的,因为TDictHelper我实现的类有一个Make将数组TPair<Key, Value>作为参数的例程;如果我将其写为以下内容,则将无法使用:
Dict := TDictHelper<Integer, string>.Make(TPair<Integer, string>.Create(1, 'one'), TPair<Integer, string>.Create(2, 'two'));
Run Code Online (Sandbox Code Playgroud)
它会起作用,但它会非常非常丑陋!
由于使用with可能有问题(特别是如果您想使用两种字典),我包含了另一种语法;不幸的是,这个不能扩展,它变得非常难看:
Dict := TDictHelper<Integer, string>.Make([1, 2], ['one', 'two']);
Run Code Online (Sandbox Code Playgroud)
此替代方案采用两个单独的键和值数组,将它们组合在Make方法中。2-3 个元素看起来没问题,但不能缩放:如果你有 10 个元素并且需要删除第 7 对怎么办?您需要对元素进行计数,这很容易出错。
这是完整的代码,不多说:
program Project25;
{$APPTYPE CONSOLE}
uses
SysUtils, Generics.Collections;
type
TDictHelper<Key, Value> = class
public
class function P(const K:Key; const V:Value): TPair<Key, Value>;
class function Make(init: array of TPair<Key, Value>): TDictionary<Key, Value>;overload;
class function Make(KeyArray: array of Key; ValueArray: array of Value): TDictionary<Key, Value>;overload;
end;
{ TDictHelper<Key, Value> }
class function TDictHelper<Key, Value>.Make(init: array of TPair<Key, Value>): TDictionary<Key, Value>;
var P: TPair<Key, Value>;
begin
Result := TDictionary<Key, Value>.Create;
for P in init do
Result.AddOrSetValue(P.Key, P.Value);
end;
class function TDictHelper<Key, Value>.Make(KeyArray: array of Key;
ValueArray: array of Value): TDictionary<Key, Value>;
var i:Integer;
begin
if Length(KeyArray) <> Length(ValueArray) then
raise Exception.Create('Number of keys does not match number of values.');
Result := TDictionary<Key, Value>.Create;
for i:=0 to High(KeyArray) do
Result.AddOrSetValue(KeyArray[i], ValueArray[i]);
end;
class function TDictHelper<Key, Value>.P(const K: Key;
const V: Value): TPair<Key, Value>;
begin
Result := TPair<Key, Value>.Create(K, V);
end;
// ============================== TEST CODE FOLLOWS
var Dict: TDictionary<Integer, string>;
Pair: TPair<Integer, string>;
begin
try
try
// Nice-looking but requires "with" and you can't work with two kinds of DictHelper at once
with TDictHelper<Integer, string> do
Dict := Make([P(1, 'one'), P(2, 'two')]);
// Use the array
for Pair in Dict do
WriteLn(Pair.Key, ' = ', Pair.Value);
Dict.Free;
// Passing the Keys and the Values in separate arrays; Works without "with" but it would
// be difficult to maintain for larger number of key/value pairs
Dict := TDictHelper<Integer, string>.Make([1, 2], ['one', 'two']);
// Use the array
for Pair in Dict do
WriteLn(Pair.Key, ' = ', Pair.Value);
Dict.Free;
except on E:Exception do
WriteLn(E.ClassName, #13#10, E.Message);
end;
finally ReadLn;
end;
end.
Run Code Online (Sandbox Code Playgroud)