Check out User.cs down below. It's a pretty simple class with three constructors: the default (parameterless) one, and one each taking the user name, and id. PowerShell will cast using the constructors of a type, so in this case, you can cast either a string or a number --or a hashtable-- to User.
We can add this type to our PowerShell session using Add-Type:
Add-Type -path User.csThe most interesting of PowerShell's special casting powers is the hashtable cast. Any class that has a default (parameterless) constructor can be created by casting a hashtable of (some of) it's settable properties:
[user]@{
Id = 1
Name = "Jaykul"
}Id Name OAuthUri
-- ---- --------
1 Jaykul
In the case of this particular User class, when we cast a number, like [User]2 it's the same as calling [User]::new(2), but the results of either are a little surprising:
Id Name OAuthUri
-- ---- --------
0 2
The number was used for the Name value, instead of the Id that we expected...
The reason for this is actually straightforward, but it's due to a combination of reasons that aren't intuitive.
The bottom line is that the numeric constructor we might have thought we were calling accepts a uint (an unsigned int), rather than a signed int, and literal numbers in PowerShell are always [int] (or [double] if they have a decimal place).
PowerShell (well, programming languages in genera) won't cast implicitly if it looses information. Implicit casting is when you try to pass a value to a method (or function) that accepts a different type of value. Explicit casting is when you specify the type by writing it out.
So for instance, a int will cast implicitly to a double, but not the other way around, because you would loose the fractional value. You can still cast it explicitly, by just specifying [double].
PowerShell simply won't call the method that accepts an unsigned int unless you specifically cast the number to an unsigned int. As far as syntax, you can double-cast it:
[User][uint]2Or you can call the constructor more explicitly:
[User]::new([uint]2)Either way, you'll get a user with an Id but no Name.
Id Name OAuthUri
-- ---- --------
2
Of course, the other part of the puzzle is why you get an unexpected result, instead of an error like:
"InvalidArgument: Cannot convert the "2" value of type "System.Int32" to type "User".
The reason is yet another PowerShell casting oddity: PowerShell can (and will) cast anything to a string implicitly, by calling it's ToString() method. That's really convenient in a shell, where you regularly want to display things as strings, but sometimes... well, something like this happens.
In other words, PowerShell will implicitly cast an integer to string, but will not cast implicitly it to uint -- so you get an unexpected constructor and result.