Powershell: Classes: an uninitialized [string] property defaults to $null rather than the empty string

Created on 16 Jul 2018  路  3Comments  路  Source: PowerShell/PowerShell

This is an inconsistency discovered by @alx9r:

If you define a class property of type [string] without assigning an initial value, its value is unexpectedly $null, even though in all other contexts PowerShell defaults [string] values to '' (the empty string) and even converts explicitly assigned $null to ''.

Steps to reproduce

class c { [string] $prop }; $null -eq [c]::new().prop
class c { [string] $prop = $null }; $null -eq [c]::new().prop
class c { [string] meth() { return $null } }; $null -eq [c]::new().meth()

Expected behavior

False
False
False

Actual behavior

True
False
False

That is, the uninitialized [string] property unexpectedly contains $null.

Environment data

PowerShell Core v6.1.0-preview.3 on macOS 10.13.5
PowerShell Core v6.1.0-preview.3 on Ubuntu 16.04.4 LTS
PowerShell Core v6.1.0-preview.3 on Microsoft Windows 10 Pro (64-bit; Version 1709, OS Build: 16299.371)
Windows PowerShell v5.1.17134.48 on Microsoft Windows 10 Pro (64-bit; Version 1709, OS Build: 16299.371)
WG-Engine

Most helpful comment

Point taken, and I agree that it鈥檚 a bit inconsistent. I guess I鈥檓 just voicing a preference for aligning with C# in this context. As you note, in many ways, it already is.

No one has ever had to learn about [NullString]::Value and been happy about it. I know it鈥檚 too late for that, but I鈥檇 hate to have it show up more than it already has to.

All 3 comments

Is this unexpected? I know that I would personally be very surprised to find string members initialized to empty strings. I would expect class members to have default values as they do in other .NET languages. Coercing null to empty string is already a confusing foot gun in other contexts, I wouldn鈥檛 want to see it extended to classes.

@mattpwhite:

The primary purpose of this issue is to show the _lack of consistency_.

I suggested resolving the inconsistency toward PowerShell-like behavior, because, as demonstrated, in the majority of cases you already _do_ get the surprising behavior in the context of custom classes - in line with non-class PowerShell behavior:

  • assigning $null to a [string]-typed property or variable
  • returning $null from a [string]-typed method.

(Ideally, PowerShell itself should also default [string] instances to $null, but that ship has sailed)

That said, in other respects classes are closer to C# behavior, not least syntactically.

So I suppose resolving the inconsistency toward C#-like behavior (allowing assigning $null to [string] variables/properties / allowing returning $null from [string]-typed methods) is another option.

Both resolutions are technically breaking changes, so a third option is to simply live with the inconsistency and merely document it.

I can't really speak to the guiding principles behind the behavior of PowerShell classes.
Perhaps @lzybkr can help out.

Point taken, and I agree that it鈥檚 a bit inconsistent. I guess I鈥檓 just voicing a preference for aligning with C# in this context. As you note, in many ways, it already is.

No one has ever had to learn about [NullString]::Value and been happy about it. I know it鈥檚 too late for that, but I鈥檇 hate to have it show up more than it already has to.

Was this page helpful?
0 / 5 - 0 ratings