5

In PowerShell one can define C# code and execute it. Passing in $null into the following simplest function shows that not null gets passed into the function

Add-Type -TypeDefinition @"
public static class foo
{
public static void fooo(string a)
{
    if(a!=null)
    {
        System.Console.WriteLine("Not Null. Is '" + a + "'");
    }
}
}
"@ -Language CSharp

Calling it as follows leads to the output Not Null. Is ''. This shows that $null was not null in C#. Methods like 'IsNullOrEmpty' or 'IsNullOrWhiteSpace' return true, so PowerShell must have implicitly converted the $null into a string.

[foo]::fooo($Null)

Any ideas why this is happening and if there is a better fix apart from rather calling String.IsNullOrEnpty in C#? NB: This happens irrespective of the C# language specified 'Add_Type'. I'm using PowerShell V5.

5
  • [foo]::fooo([String] $null), [foo]::fooo($null -as [String]), and $s = $null; [foo]::fooo($s) all yield the same result. If the type of parameter a is changed from string to object then fooo no longer prints any output. That suggests PowerShell is trying to be "smart" in its handling of string parameters. Commented Aug 15, 2016 at 16:39
  • The same behavior can be observed with the new class support in PowerShell 5.0 (class foo { static fooo([String] $a) { if ($a -ne $null) { [Console]::WriteLine("Not Null. Is '" + $a + "'"); } } }; [foo]::fooo($null);) as well as plain old PowerShell functions (function fooo([String] $a) { if ($a -ne $null) { [Console]::WriteLine("Not Null. Is '" + $a + "'"); } }; fooo $null;), so this must be how PowerShell handles string parameters in general. Commented Aug 15, 2016 at 16:51
  • Where are you defining a? Commented Aug 15, 2016 at 18:09
  • Possible duplicate of Possible to pass null from Powershell to a .Net API that expects a string? Commented Aug 16, 2016 at 18:36
  • Thanks for your investigation. Seems like this is just PowerShell trying to be overly helpful. I knew that PowerShell sometimes casts objects without asking to be 'helpful' but I did not expect it to actually instantiate it an object. I suppose using String.IsNullOrEmpty() in C# code is the best solution to deal with this problem. Commented Aug 17, 2016 at 23:30

1 Answer 1

6

Evidently the solution is "don't pass $null to a [String] parameter if you want a $null [String]". There is a special [NullString] class that should be used instead.

PS > [foo]::fooo($Null)
Not Null. Is ''
PS > [foo]::fooo([NullString]::Value)
PS >

I can't find any mentions of the need to use [NullString] in the PowerShell documentation, nor does the source code for the NullString class include any comments explaining its purpose.

Sign up to request clarification or add additional context in comments.

1 Comment

See documentation NullString Class. This possibility was new in PowerShell 3 (since 2012).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.