为什么 TJSONObject.AddPair 结果是 Self?
Why does TJSONObject.AddPair results Self?
我注意到 TJSONObject.AddPair
函数结果 Self
而不是新创建的对象:
例如,在 System.JSON
单元中,我看到以下代码:
function TJSONObject.AddPair(const Str: string; const Val: string): TJSONObject;
begin
if (not Str.IsEmpty) and (not Val.IsEmpty) then
AddPair(TJSONPair.Create(Str, Val));
Result := Self;
end;
我期待这样的事情:
function TJSONObject.AddPair(const Str: string; const Val: string): TJSONObject;
begin
if (not Str.IsEmpty) and (not Val.IsEmpty) then
Result := AddPair(TJSONPair.Create(Str, Val));
else
Result := nil;
end;
我觉得这很不寻常,是 Delphi XE7 错误还是他们这样做有任何 technical/practical 原因?
返回 Self
是称为 fluent interface 的常见编码模式。
它允许您继续调用同一对象,创建方法链,而无需为每次调用引用对象变量。这使代码更具可读性,另一方面更难调试。
var
Obj: TJSONObject;
begin
Obj := TJSONObject.Create
.AddPair('first', 'abc')
.AddPair('second', '123')
.AddPair('third', 'aaa');
...
end;
相当于
var
Obj: TJSONObject;
begin
Obj := TJSONObject.Create;
Obj.AddPair('first', 'abc');
Obj.AddPair('second', '123');
Obj.AddPair('third', 'aaa');
...
end;
生成的 JSON 对象将如下所示:
{
"first": "abc",
"second": "123",
"third": "aaa"
}
这种编码风格在具有自动内存管理的语言中更为普遍,因为您不需要引入中间变量。
例如,如果您需要 JSON 字符串,您将使用以下结构:
var
s: string;
begin
s := TJSONObject.Create
.AddPair('first', 'abc')
.AddPair('second', '123')
.AddPair('third', 'aaa')
.Format(2);
...
end;
Delphi 中上述代码的问题在于它会造成内存泄漏,因为您无法释放中间对象。因此,更常见的是使用 fluent interface 模式结合引用计数 类,其中自动内存管理将处理任何中间对象实例的释放。
我注意到 TJSONObject.AddPair
函数结果 Self
而不是新创建的对象:
例如,在 System.JSON
单元中,我看到以下代码:
function TJSONObject.AddPair(const Str: string; const Val: string): TJSONObject;
begin
if (not Str.IsEmpty) and (not Val.IsEmpty) then
AddPair(TJSONPair.Create(Str, Val));
Result := Self;
end;
我期待这样的事情:
function TJSONObject.AddPair(const Str: string; const Val: string): TJSONObject;
begin
if (not Str.IsEmpty) and (not Val.IsEmpty) then
Result := AddPair(TJSONPair.Create(Str, Val));
else
Result := nil;
end;
我觉得这很不寻常,是 Delphi XE7 错误还是他们这样做有任何 technical/practical 原因?
返回 Self
是称为 fluent interface 的常见编码模式。
它允许您继续调用同一对象,创建方法链,而无需为每次调用引用对象变量。这使代码更具可读性,另一方面更难调试。
var
Obj: TJSONObject;
begin
Obj := TJSONObject.Create
.AddPair('first', 'abc')
.AddPair('second', '123')
.AddPair('third', 'aaa');
...
end;
相当于
var
Obj: TJSONObject;
begin
Obj := TJSONObject.Create;
Obj.AddPair('first', 'abc');
Obj.AddPair('second', '123');
Obj.AddPair('third', 'aaa');
...
end;
生成的 JSON 对象将如下所示:
{
"first": "abc",
"second": "123",
"third": "aaa"
}
这种编码风格在具有自动内存管理的语言中更为普遍,因为您不需要引入中间变量。
例如,如果您需要 JSON 字符串,您将使用以下结构:
var
s: string;
begin
s := TJSONObject.Create
.AddPair('first', 'abc')
.AddPair('second', '123')
.AddPair('third', 'aaa')
.Format(2);
...
end;
Delphi 中上述代码的问题在于它会造成内存泄漏,因为您无法释放中间对象。因此,更常见的是使用 fluent interface 模式结合引用计数 类,其中自动内存管理将处理任何中间对象实例的释放。