首页 > 解决方案 > 如何在 PowerShell 中覆盖 Collection 对象的“成员枚举”行为

问题描述

想象一下,我创建了一个 C# 类,该类扩展Collection<T>为特定用例添加附加功能。

public class MyCollection<T> : Collection<T> {}

现在,如果我将这个类导入到我的 PowerShell 脚本中,并实例化这样一个对象,T则从所述对象调用该对象的成员方法将执行一种“魔术”,其中它一个接一个地调用成员方法对于集合中的每个项目。

请注意,在此示例中,我使用的是我自己的MyCollection[String],而不是Collection[String]没有区别。

Add-Type -Path ".\MyCollection.cs"
$test = New-Object -TypeName MyCollection[String]
$test.Add("one")
$test.Add("two")
$test.Add("three")
$test.Length
# 3
# 3
# 5

这种行为或多或少被称为“成员枚举”。去这里解释我在说什么:https ://devblogs.microsoft.com/powershell/new-v3-language-features/

由于它实际上并没有运行 ForEach-Object cmdlet(请参阅上面的链接),我希望找到实际发生的情况以及如果可能的话,我可以如何覆盖该行为而无需做出骇人听闻的解决方法(例如创建包装器)对象类中的每个方法的 MyCollection 类中的方法)。

例如:

public class MyCollection<T> : Collection<T> {
    public new void ForEach-Object(this Action action) {
        DoSomethingAsync(this, action);
    }
}

我故意使用上面的无效语法来帮助说明问题。我真的不知道这是否可以做到。

或者,如果有另一种方法可以在不使用我之前提到的解决方法的情况下实现相同的目标,我也会有兴趣听到这些想法。

标签: c#powershellpowershell-3.0

解决方案


您不能阻止 PowerShell 的成员枚举(也不会使您的集合不可枚举),因为它是内置于.成员访问运算符中的行为。

但是,如果您引用集合对象本身上存在的属性,使用该集合级别的属性,覆盖成员枚举。

也就是说,$test.Count- 假设它.Count是您的集合类型的(实例)成员 - 将仅返回3集合中元素的数量。

这个 GitHub 建议要求成员枚举使用不同的语法(运算符),但只要 PowerShell 保持向后兼容性(可能是永远的), 的行为.就不会改变。


推荐阅读