2

多くのデリゲートを使用する .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 スクリプト ブロックが実際の double 値ではなく PSObject を返すことです。私の .NET API は PowerShell について何も知りません。また、この特定のシナリオに特別な処理を追加できるように、PowerShell DLL への参照を追加したくありません。

スクリプト ブロックが PSObject ではなく実際の値の型を返すようにする方法はありますか? または、.NET ライブラリが PSObject を処理するための PowerShell に依存しない方法はありますか?

4

1 に答える 1

4

PowerShell は、適切と思われるものを PSObject でラップします。任意のスクリプト ブロックを受け入れる場合、それを回避する明確な方法はありません。ある程度の規律があれば、PSObject をアンラップするスクリプト ブロックを記述できます。たとえば、次のようにすると問題なく動作する可能性があります。

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

可能であれば、より具体的な戻り値の型を持つデリゲートを API に持たせることをお勧めします。

public static void DoSomethingWithDouble(Func<double> myFunc)

この場合、PowerShell は戻り値をデリゲートが期待する型に変換します。戻り値の型が PSObject の場合、PowerShell は PSObject が単純にオブジェクトに変換されることを認識しているため、ラップを解除しませんが、戻り値の型がそれ以外の場合、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 は 2 行目で から double への変換を実行します。

これらの最後の 2 つのオプションは、実際の API にはうまく適合しない可能性がありますが、理解する価値のあるオプションです。

于 2013-12-27T17:52:51.537 に答える