尝试定义以Tuple为键、ArrayList为值的Dictionary失败求助
为什么PowerShell会把Dictionary中的ArrayList值静默转为System.Array?
问题复现代码
# Create dictionary $mydict = [Collections.Generic.Dictionary[[Tuple[int,int]],Collections.ArrayList]]::new() # Add an empty Arraylist to a key $mydict.Add([Tuple]::Create(0,0),[Collections.ArrayList]::new()) # Try to add an item to this new arraylist $mydict[(0,0)].Add(1) MethodInvocationException: Exception calling "Add" with "1" argument(s): "Collection was of a fixed size." # And sure enough: $mydict[(0,0)].IsFixedSize True $mydict[(0,0)].GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array
原因解析
这是PowerShell的成员访问枚举特性导致的:当你通过$mydict[(0,0)]访问字典值时,PowerShell发现目标对象(ArrayList)实现了IEnumerable接口,会自动枚举这个集合的所有元素,并将枚举结果包装成一个固定大小的Object[]数组返回给你。所以你实际操作的不是原本存入的ArrayList,而是它被转换后的数组副本,自然会触发“固定大小集合”的错误。
解决方法
有三种可行的解决方式:
显式使用
Item属性访问
直接调用字典的Item属性,绕过PowerShell的成员访问枚举:$mydict.Item([Tuple]::Create(0,0)).Add(1)用括号强制求值
通过括号包裹访问表达式,强制PowerShell返回原始的ArrayList对象,而不是枚举后的数组:($mydict[(0,0)]).Add(1)改用泛型列表替代ArrayList
ArrayList是旧的非泛型集合,PowerShell对泛型集合(比如List<object>)的处理更友好,不会触发这种隐式转换:$mydict = [Collections.Generic.Dictionary[[Tuple[int,int]],Collections.Generic.List[object]]]::new() $mydict.Add([Tuple]::Create(0,0), [Collections.Generic.List[object]]::new()) $mydict[(0,0)].Add(1) # 正常执行无报错
内容的提问来源于stack exchange,提问作者GodEater
相关产品推荐
相关产品推荐

