# encoding: ascii
# api: csharp
# title: Dict context
# description: PowerShell has numeric and string contexts:
# version: 0.1
# type: class
# author: Public Domain
# license: CC0
# x-poshcode-id: 5178
# x-archived: 2014-05-24T12:12:27
# x-published: 2014-05-22T01:19:00
#
# [int]$a = $null # $a will be 0 instead of $null
# [string]$b = $null # $b will be ‘’ instead of $null
# [dict()] does a similar thing for dictionaries:
# [dict()]$c = $null # $c will be @{} instead of $null
#
<#
[dict()]$lhs = $rhs
Is basically equivalent to this pseudo-code:
$lhs = $(if ($null -eq $rhs) {
@{}
} elseif ($rhs -is [System.Collections.IDictionary] -or $rhs -is [System.Collections.Generic.IDictionary`2] -or $rhs -is [System.Collections.Generic.IReadOnlyDictionary`2])) {
$rhs
} else {
throw ([ArgumentException]"Value is not a dictionary type")
})
Or in plain English, [dict()] converts $null to @{}, passes any [IDictionary]-like types as is, and fails otherwise.
NOTES:
PowerShell doesn't consider [IReadOnlyDictionary`2]s to be dictionaries, this code does.
PowerShell doesn't consider [IDictionary`2]s that don't implement [IDictionary] to be dictionaries, this code does.
#>
Add-Type -TypeDefinition @'
using System;
using System.Management.Automation;
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class DictAttribute : ArgumentTransformationAttribute {
public override Object Transform(EngineIntrinsics engineIntrinsics, Object inputData) {
Object o = inputData;
PSObject pso = inputData as PSObject;
if (pso != null) {
o = (pso != System.Management.Automation.Internal.AutomationNull.Value) ? pso.BaseObject : null;
}
if (o == null)
return new System.Collections.Hashtable();
if (o is System.Collections.IDictionary)
return inputData;
foreach (Type t in o.GetType().GetInterfaces()) {
if (t.IsGenericType) {
Type g = t.GetGenericTypeDefinition();
if (g == typeof(System.Collections.Generic.IDictionary<,>) ||
g == typeof(System.Collections.Generic.IReadOnlyDictionary<,>))
{
return inputData;
}
}
}
throw new ArgumentException("Value is not a dictionary type");
}
}
'@