Delphi中Assigned(MyObj)与MyObj<>nil写法替换的原因问询
Assigned vs. nil Comparison in Delphi/FireMonkey: What's the Difference?
Great question! Let's dive into the nuances between if Assigned(MyObj) then and if (MyObj <> nil) then in Delphi—especially in the FireMonkey context—and unpack why Embarcadero might swap these around, plus which one you should prefer.
Core Behavior & Compiler Optimizations
First, let's break down the technical differences based on what you're checking:
- For TObject descendants (FireMonkey objects like
TForm,TButton):These two checks are functionally identical. The Delphi compiler optimizesAssigned(MyObj)to a direct nil comparison under the hood—no extra function call overhead, no performance difference.Assignedwas originally built for procedure/function pointers (more complex than simple object references), but over time it became a common shorthand for object nil checks too. - For Interfaces:In older Delphi versions (pre-2009), comparing an interface to
nilwould trigger implicit_AddRefand_Releasecalls, which could mess with reference counts unexpectedly.Assigned(MyIntf)avoids this entirely by only checking if the underlying pointer is nil, no reference count operations involved. Modern compilers have fixed this edge case for interface nil comparisons, butAssignedis still the safer, more portable choice here. - For Procedure/Function Pointers (like
TProcor custom method pointers):This is whereAssignedis non-negotiable. These pointers are often structured as records (containing both a code pointer and context, like the object instance for a method). Comparing them directly tonilonly checks part of that record, which can lead to false positives (thinking a pointer is valid when it's not).Assigned()properly validates the entire structure to ensure it's a callable, valid pointer.
Why Embarcadero Might Swap Them in FireMonkey Code
There are a few plausible reasons for this switch:
- Style Consistency:Many development teams prefer the explicit
MyObj <> nilbecause it reads like plain English—"if this object isn't nil"—which can be easier for new Delphi developers to parse. Embarcadero might be standardizing on this style across parts of the FireMonkey codebase to keep things uniform. - Evolving Compiler Capabilities:As compilers got better at optimizing
Assigned()into direct nil checks for objects, the practical technical difference between the two vanished. So swapping to<> nilbecomes purely a stylistic choice rather than a performance or safety one. - Niche Edge Case Avoidance (Rare):In very rare scenarios—like if a class incorrectly overrides the equality operator—
MyObj <> nilcould behave unexpectedly.Assigned()bypasses operator overrides by checking the raw pointer directly. That said, this is a corner case; well-written FireMonkey classes don't mess with equality operators for nil checks.
Which Should You Use?
- For FireMonkey objects (TObject descendants):Pick whichever style fits your team's coding guidelines. There's no technical advantage to either.
- For interfaces or procedure/function pointers:Always use
Assigned(). It's safer, avoids potential reference count bugs, and properly validates complex pointer types.
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

