在 Delphi 中逃离 Assigned() 链
Escape from chain of Assigned() in Delphi
有时我在源代码中看到由 Assigned() 在对象深处进行的长链检查,例如
if Assigned (ASomeObj)
and Assigned (ASomeObj.Session)
and Assigned (ASomeObj.Session.UserInfo)
and Assigned (ASomeObj.Session.UserInfo.SomeFactsList)
then
// to do some actions
这是通过nil检查所有中间实体的方法。也许有人知道在条件部分裁剪链的方法吗?
作为一个想法被关注到
try
if Assigned (ASomeObj.Session.UserInfo.SomeFactsList)
then
// to do some actions
except
end;
是否存在简化的路径?
如何阅读源码清晰易懂?
据我所知,在 Csharp 中存在“?”使用类似 ASomeObj?.Session?.UserInfo?.SomeFactsList 的运算符以供 Null
检查
TL;DR Delphi 语言中没有这样的运算符,我认为我们不会很快得到它。但是有一些好的做法可以解决这个问题。阅读更多 ...
让我们从问题的底部开始。
As I know in CSharp exist ?
operator for using like
ASomeObj?.Session?.UserInfo?.SomeFactsList
for check by null
首先在C#中没有?
运算符,但是有些运算符中有?
:
?:
ternary conditional operator
??
(C# 2+)null-coalescing operator
?.
和 ?[]
(均为 C# 6+)null-conditional operator
??=
(C# 8+)null-coalescing assignment operator
您显然指的是 ?.
a.k.a。 safe navigation operator 甚至
Delphi 语言中没有这样的运算符,考虑到甚至还没有真正的三元条件运算符,我认为我们不会很快得到它:
您不是唯一提出要求的人 - add support for null-conditional operator (RSP-21323) 有一项开放功能请求。
FWIW:来自 RemObjects Software 的 Oxygene 语言(免责声明:没有关系)为此目的 colon operator。
我们从这里去哪里?我首先建议您重新考虑您的设计(正如问题下的评论所指出的那样)。
让我引用Just Say No to Nulls (or Refactoring Your Way to Programmer Bliss):
The truth is, when we find ourselves wading through endless object hierarchies such as these, that there is what we call a code smell. And it’s a pretty good indication that we might want to revisit our design. A true OO design is composed of nice little well behaved classes that expose methods we can call on to have them do things for us. These classes abstract the nitty gritty behind the scenes details and just do it (often without the need to return any value at all).
dog.bark()
not dog.getAnatomy().getVoiceBox().EmitSound("woof")
另一种选择是使用 Null object pattern 使中间对象不 nil
。这将帮助您摆脱链式 Assigned
检查。
廉价而肮脏的解决方案是直接在 ASomeObj
上引入 shorthand 属性 SomeFactsList
或 class 助手,所以至少你不需要到处重复自己的话,如果有的话。
进一步阅读:
有时我在源代码中看到由 Assigned() 在对象深处进行的长链检查,例如
if Assigned (ASomeObj)
and Assigned (ASomeObj.Session)
and Assigned (ASomeObj.Session.UserInfo)
and Assigned (ASomeObj.Session.UserInfo.SomeFactsList)
then
// to do some actions
这是通过nil检查所有中间实体的方法。也许有人知道在条件部分裁剪链的方法吗?
作为一个想法被关注到
try
if Assigned (ASomeObj.Session.UserInfo.SomeFactsList)
then
// to do some actions
except
end;
是否存在简化的路径? 如何阅读源码清晰易懂?
据我所知,在 Csharp 中存在“?”使用类似 ASomeObj?.Session?.UserInfo?.SomeFactsList 的运算符以供 Null
检查TL;DR Delphi 语言中没有这样的运算符,我认为我们不会很快得到它。但是有一些好的做法可以解决这个问题。阅读更多 ...
让我们从问题的底部开始。
As I know in CSharp exist
?
operator for using like
ASomeObj?.Session?.UserInfo?.SomeFactsList
for check bynull
首先在C#中没有?
运算符,但是有些运算符中有?
:
?:
ternary conditional operator??
(C# 2+)null-coalescing operator?.
和?[]
(均为 C# 6+)null-conditional operator??=
(C# 8+)null-coalescing assignment operator
您显然指的是 ?.
a.k.a。 safe navigation operator 甚至
Delphi 语言中没有这样的运算符,考虑到甚至还没有真正的三元条件运算符,我认为我们不会很快得到它:
您不是唯一提出要求的人 - add support for null-conditional operator (RSP-21323) 有一项开放功能请求。
FWIW:来自 RemObjects Software 的 Oxygene 语言(免责声明:没有关系)为此目的 colon operator。
我们从这里去哪里?我首先建议您重新考虑您的设计(正如问题下的评论所指出的那样)。
让我引用Just Say No to Nulls (or Refactoring Your Way to Programmer Bliss):
The truth is, when we find ourselves wading through endless object hierarchies such as these, that there is what we call a code smell. And it’s a pretty good indication that we might want to revisit our design. A true OO design is composed of nice little well behaved classes that expose methods we can call on to have them do things for us. These classes abstract the nitty gritty behind the scenes details and just do it (often without the need to return any value at all).
dog.bark()
notdog.getAnatomy().getVoiceBox().EmitSound("woof")
另一种选择是使用 Null object pattern 使中间对象不 nil
。这将帮助您摆脱链式 Assigned
检查。
廉价而肮脏的解决方案是直接在 ASomeObj
上引入 shorthand 属性 SomeFactsList
或 class 助手,所以至少你不需要到处重复自己的话,如果有的话。
进一步阅读: