I’ve been reading Jeffrey Snover's discussions on ENUMs over on the PowerShell Team blog (here, and here). I knew most of this stuff and have been playing with Enums and PowerShell for a while. I’ve created a bunch of sample scripts I’ve uploaded both to the MDSN Wiki and to my PowerShell Scripts blog. This morning, I stumbled upon an interesting use of Enums – parsing strings into Integer values, as shown on the MSDN Library at http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles.aspx.
Effectively want I wanted to do was to convert the following C# code to PowerShell:
- // Parse the string, allowing a leading sign, and ignoring leading and trailing white spaces.
- num = " -45 ";
- val = int.Parse(num, NumberStyles.AllowLeadingSign |
- NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite);
- Console.WriteLine("'{0}' parsed to an int is '{1}'.", num, val);
Initially, I could not work out how to use the enums (In System.Globalization.NumberStyles). Thanks to Shay Levy, it turns out to be remarkably easy (although not quite as succinct as in C'#). Basically, in true PowerShell style, every enum value is just an object. Objects have properties, and one property of an enum value is “value__” as demonstrated here:
PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign
AllowLeadingSign
PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign | gmTypeName: System.Globalization.NumberStyles
Name MemberType Definition
---- ---------- ----------
CompareTo Method System.Int32 CompareTo(Object target)
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
GetTypeCode Method System.TypeCode GetTypeCode()
ToString Method System.String ToString(), System.String ToString(String format, IFormatPr...
value__ Property System.Int32 value__ {get;set;}
MSDN ScriptMethod System.Object MSDN();PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign.value__
4
PSH [D:\foo]:
As you can see from this output, the enum [System.Globalization.NumberStyles]::AllowLeadingSign displays normally the value “AllowLeadingSign” , but if you use the .value__ property on this enum value, you get back a number – in this case a decimal 4 (0x0004). You can then combine these as follows to convert the above C# Code into PowerShell:
- $num = " -45 ";
- $val = [system.int32]::Parse($num,
- [System.Globalization.NumberStyles]::AllowLeadingSign.value__ +
- [System.Globalization.NumberStyles]::AllowLeadingWhite.value__ +
- [System.Globalization.NumberStyles]::AllowTrailingWhite.value__)
- "'{0}' parsed to an int is '{1}'." -f $num, $val
Thanks to Shay Levy for his post in the PowerShell newsgroup for helping me to work this out. FWIW: you can the results of this up on the MSDN Library and on my PowerShell Scripts blog.
3 comments:
In PowerShell, you can typically just use the string for an enum, like: "AllowLeadingSign" instead of [System.Globalization.NumberStyles]::AllowLeadingSign
Additionally, you can combine enum values as a comma-separated string, instead of using -bor (bitwise or, which is what you had in the C# example) or addition (which works sometimes, but is not the correct way to combine flag enums).
In the case of Int.Parse, you have to look out for the overloads of the function, so you must explicitly cast your string to the enum type:
[int]::parse( " -54 ", [Globalization.NumberStyles]"AllowLeadingSign, AllowLeadingWhite, AllowTrailingWhite" )
Isn't that easier?
After I posted a moment ago, I realized there's an easier way, in this case. Looking at that post by Jeffrey about enums, you can use [Enum]::GetValues like this:
[enum]::GetValues([System.Globalization.NumberStyles]) | %{ "{0,3} {1}" -f $([int]$_),$_ }
And I also noticed that if you just type:
[System.Globalization.NumberStyles]"AllowLeadingSign,AllowLeadingWhite,AllowTrailingWhite"
The console returns: Integer
It turns out that [System.Globalization.NumberStyles]::Integer is equivalent to that manual combination :)
Additionally, some perhaps "further" information can be had by doing [System.Globalization.NumberStyles].GetFields() which tells you well err more kind of information regarding the enum fields.
Post a Comment