4

To use a .net type, I normally do Add-Type then use New-Object:

Add-Type -AssemblyName "System.Windows.Forms"
$win = New-Object Windows.Forms.Form

But really I can also just use square bracket syntax to refer the type and use static methods:

$win = [System.Windows.Forms.Form]::new()

What's the difference between them? I have not found much documentation with square bracket syntax for .Net types. All documentation I found for square brackets are for the arrays.

mklement0
  • 382,024
  • 64
  • 607
  • 775
SwiftMango
  • 15,092
  • 13
  • 71
  • 136
  • 1
    You can use the 2nd option tho it requires PS 5.1+ I think – Santiago Squarzon Aug 01 '21 at 18:33
  • the 2nd method is faster and rather more obvious when reading the code. `New-Object` and `Add-Member` are both known to be quite slow. – Lee_Dailey Aug 01 '21 at 18:34
  • 1
    Using the `new()` static method is faster, but not just that, when you enter such method to create an object without the brackets, you can see all overloaded constructor definitions (if there are any..) to help you choose. Try for instance `[datetime]::new` and hit enter. P.S. I wouldn't use `[System.Reflection.Assembly]::LoadWithPartialName()` anymore as it is [obsolete](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.loadwithpartialname?view=net-5.0#System_Reflection_Assembly_LoadWithPartialName_System_String_) – Theo Aug 01 '21 at 18:57

1 Answers1

5

Add-Type is only used to load .NET types into a session (or to define them by ad hoc compilation).

To use these types by calling their constructors, you have two options:

  • In any PowerShell version:

  • Preferably, in PowerShell v5+:

    • Use a type literal ([...]) and call the type's (PowerShell-supplied) static ::new() method.
    • See this answer for more information about PowerShell type literals.

As Lee_Dailey and Theo note, using the static ::new() method has several advantages:

  • Calling ::new() is faster; with a single or only a few constructor calls that probably won't matter, but it may in loops.

  • Executing just ::new without parentheses shows all constructor overloads, which is a convenient way to find out what constructor arguments are needed and what their types are.

  • Calling ::new() doesn't wrap the newly created instance in a - mostly - invisible [psobject] wrapper, the way that New-Object and cmdlets in general do; while this wrapper is mostly benign, it can cause subtle differences in behavior - see GitHub issue #5579.

Note that, due to PowerShell's two fundamental parsing modes, New-Object and ::new() require different syntax, as discussed in this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775