Skip to content

Avoid New-Object #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Jaykul opened this issue Jun 23, 2016 · 4 comments
Open

Avoid New-Object #60

Jaykul opened this issue Jun 23, 2016 · 4 comments

Comments

@Jaykul
Copy link
Member

Jaykul commented Jun 23, 2016

In modern PowerShell, you should almost always avoid New-Object, because it is much slower than other methods of creating objects, like using the constructor directly via ::new( or casting a hash-table. Both the [PSObject]::new() constructor and casting are supported in all actively supported versions of PowerShell.

As always, there are some exceptions to this rule, such as when you need to create a type from a string input, or need to create a ComObject, and you may sometimes get more readable code, such as when you need to pass arguments to the constructor as well as property values.

It's also worth pointing out there is at least one special case: hash tables. PowerShell's normal hash tables, created with literal @{ key = "value" } syntax, are case insensitive, but hash tables created via constructor syntax [hashtable]::new() or New-Object Hashtable use the .NET default case sensitive hash tables.

@iRon7
Copy link

iRon7 commented Dec 6, 2024

I think that the use New-Object should be general avoided as it is legacy (change issue title?)
and even counts for any object creation including something like: New-Object System.Drawing.Size(800, 600) --> [System.Drawing.Size]::new(800, 600)

@Jaykul
Copy link
Member Author

Jaykul commented Dec 16, 2024

What I mean above is that New-Object should not be used to create hash tables -- because it produces unexpected and incorrect results. That is, you should almost always use the literal @{ ... } hash table, not because New-Object is slower, and totally unnecessary, but because the cmdlet makes the hash table case sensitive which is unexpected, and usually wrong, in PowerShell. Of course, if you need a case sensitive hash table, then you have to use the [hashtable]::new() or New-Object hashtable.

What the article points out is that New-Object is quite a bit slower to create PSObject than using the new casting syntax with [PSCustomObject]@{ ... } -- however, it is backward compatible to older versions of PowerShell. It literally always works, even in old versions where the new syntax does not.

We could also make this case generically for any type that has a default/empty constructor, since you can then cast a hashtable to them.

And of course (as you wrote in the linked issue), we could make that case for calling the constructor using the ::new syntax -- although that's a totally different situation than the PSCustomObject syntax (calling parameterized constructors, vs the default constructor and setting properties), and is even newer.

In the general case, you should avoid New-Object when you can use either of the new syntaxes. However, although it's slower to use New-Object than the ::new(...) operator or the cast operator, the cmdlet works on older versions, and if you need to both pass constructor arguments and set a bunch of property values, it can still be a lot more readable (albeit probably still slower).

@iRon7
Copy link

iRon7 commented Dec 16, 2024

What I mean above is that New-Object should not be used to create hash tables...

I understand your point and completely agree with the ins and outs related to this issue (and the one I mentioned).
By the way, I reported a PowerShell issue once that shows the implied disadvance of using the literal initializer: #23986 PSCustomObject unnoticeably merges similar keys 😀.

Anyways, what I mean was that the PowerShell Practice And Style Guide might include some (more general) guidance about the use of the New-Object cmdlet vs literal initializer (whatever the direction might be).

I understand also that this differs from your initial request, so let me know if you think it might make more sense to open a new issue for this instead.

@Jaykul
Copy link
Member Author

Jaykul commented Dec 17, 2024

You are right that it would be worthwhile making the general recommendation as well. I have changed the original post to reflect what I would propose...

@Jaykul Jaykul changed the title Avoid New-Object Hashtable Avoid New-Object Dec 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants