防止PowerShell将值类型包装在PSObjects中

3

我有一个使用许多委托的.NET API。我的API有一些类似以下方法:

public static class MyClass
{
    public static void DoSomethingWithString(Func<object> myFunc)
    {
        string myStringValue = myFunc().ToString();
        Console.WriteLine(myStringValue);
    }

    public static void DoSomethingWithDouble(Func<object> myFunc)
    {
        object unparsedValue = myFunc();
        double parsedValue = Convert.ToDouble(unparsedValue);
        Console.WriteLine(parsedValue);
    }
}

现在在PowerShell中,我有以下内容:

[MyClass]::DoSomethingWithString({ "Hello" }); # No error here
[MyClass]::DoSomethingWithDouble({ 123.4 });   # InvalidCastException - can't convert a PSObject to double

问题在于我的PowerShell脚本块返回的是PSObject而不是实际的双精度值。我的.NET API对PowerShell一无所知,我不想添加PowerShell DLL的引用,只是为了针对这个特定情况添加特殊处理。
有没有办法让我的脚本块返回实际值类型而不是PSObject?或者,有没有适用于所有PowerShell版本的方法,让我的.NET库处理PSObject?

为什么不直接获取字符串值(使用 .tostring()),然后再进行转换呢?它不知道如何转换 PSObject,但它知道如何转换字符串。 - mjolinor
@mjolinor,我肯定想避免那种解决方案,但看起来那是我的唯一选择。 - Phil
1个回答

5

PowerShell会根据需要将东西包装在PSObject中,当接受任意脚本块时,没有简单的方法可以避免这种情况。通过一些纪律性的写法,您可以编写解包PSObject的脚本块,例如以下内容可能会很好地工作:

[MyClass]::DoSomethingWithDouble({ (123.4).PSObject.BaseObject })

如果可能的话,更好的选择是让您的API使用具有更具体返回类型的委托。
public static void DoSomethingWithDouble(Func<double> myFunc)

在这种情况下,PowerShell将返回值转换为委托所期望的类型。当返回类型为PSObject时,PowerShell知道PSObject可以轻松转换为object,因此它不会解包,但如果返回类型几乎是其他任何类型,PowerShell会通过解包PSObject来强制进行转换。
为了完整起见,如果您正在使用PowerShell V3,另一个选项是使用C#关键字dynamic,类似于:
public static void DoSomethingWithDouble(Func<object> myFunc)
{
    dynamic unparsedValue = myFunc();
    double parsedValue = (double)(unparsedValue);
    Console.WriteLine(parsedValue);
}

当unparsedValue是PSObject时,即使您的C#代码中没有引用任何PowerShell程序集,PowerShell也会在第二行执行从double转换的操作。
请注意,这两个选项可能不适合您的实际API,但值得了解。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接