9

Powershell は、次のような .NET コードを呼び出すことができることを知っています。

PS> [Reflection.Assembly]::LoadFile(($ScriptDir + ".\SharpSvn-x64\SharpSvn.dll"))
PS> $SvnClient = New-Object SharpSvn.SvnClient

outそして、C# に引数がある場合、Powershell には[ref]次のような引数があることを知っています。

PS> $info = $null
PS> $SvnClient.GetInfo($repo.local, ([ref]$info))

True

PS> $info

(...long output snipped...)
NodeKind           : Directory
Revision           : 16298
Uri                : http://server/path/to/remoterepo
FullPath           : C:\path\to\localrepo
(...long output snipped...)

また、C# では、SharpSvn ライブラリがSvnClient.Update() メソッドに対して行うように、関数をオーバーロードできることを知っています。

  1. Update(ICollection(String))- 指定されたパスを最新 (HEAD) リビジョンに再帰的に更新します
  2. Update(String)- 指定されたパスを最新 (HEAD) リビジョンに再帰的に更新します
  3. Update(ICollection(String), SvnUpdateArgs)- 指定されたパスを指定されたリビジョンに更新します
  4. Update(ICollection(String), SvnUpdateResult)- 指定されたパスを最新 (HEAD) リビジョンに再帰的に更新します
  5. Update(String, SvnUpdateArgs)- 指定されたパスを再帰的に更新します
  6. Update(String, SvnUpdateResult)- 指定されたパスを最新 (HEAD) リビジョンに再帰的に更新します
  7. Update(ICollection(String), SvnUpdateArgs, SvnUpdateResult)- 指定されたパスを指定されたリビジョンに更新します
  8. Update(String, SvnUpdateArgs, SvnUpdateResult)- 指定されたパスを最新 (HEAD) リビジョンに再帰的に更新します

しかし、これらすべてをまとめたい場合はどうすればよいでしょうか。Update()たとえば、文字列と SvnUpdateResult を受け取るの 6 番目のバージョンを呼び出したい場合、 SvnUpdateResult は C# の out オブジェクトですか? 私の最初の本能は、次のようなことを試すことでした:

PS> $repopath = "C:\path\to\localrepo"
PS> $update = $null
PS> $svnclient.update($repopath, [ref]$update)

Multiple ambiguous overloads found for "Update" and the argument count: "2".
At line:1 char:18
+ $svnclient.update <<<< ($repopath, [ref]$update)
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

OK、多分私は引数をキャストする必要がありますか?

PS> $svnclient.update([string]$repopath, [ref][SharpSvn.SvnUpdateResult]$update)

Multiple ambiguous overloads found for "Update" and the argument count: "2".
At line:1 char:18
+ $svnclient.update <<<< ([string]$repopath, [ref][SharpSvn.SvnUpdateResult]$update)
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

しかし、それもうまくいかないようです。私が試した他のこと:

  • $updateとしてキャスト[SharpSvn.SvnUpdateResult][ref]- つまり、キャストした順序を逆にします。その結果、「[ref] は型変換シーケンスの最後の型にしかできません」というエラーが発生します。
  • 使用前に$updateキャスト: . これにより、上記で遭遇したのと同じ「複数のあいまいなオーバーロード」エラーが発生しますSharpSvn.SvnUpdateResult$update = [SharpSvn.SvnUpdateResult]$null
  • 使用前に$updateキャスト: . これにより、エラーが発生します:「型 "System.Management.Automation.PSReference" の "System.Management.Automation.PSReference" 値を型 "SharpSvn.SvnUpdateResult" に変換できません。」ref$update = [ref]$null

それを2回キャストすることが問題のようです-最後のキャストは最初のキャストをオーバーライドするだけで、互いに補完しません。これは何が起こっているのですか?何かを2回キャストする方法はありますか? この問題を回避する別の方法はありますか?

助けてくれてありがとう。

4

5 に答える 5

1

クラスの out パラメーターを使用して呼び出すメソッドと、同様のシグネチャを持つ別のオーバーロードがある場合、PowerShell に問題があるようです (クラスは、このシグネチャの任意のクラスにすることができます)。

この問題の簡単な再現を作成し、PowerShellの問題を提出しました。

于 2016-12-28T04:27:56.327 に答える
1

これを正しくするのはかなり難しいようです。

これはどのバージョンの PowerShell ですか? SvnUpdateArgsとは関連していますかSvnUpdateResult(つまり、1 つのクラスが別のクラスから派生していますか)。ないと仮定します。

私が作成した同様のシナリオに基づいて、現在のバージョン (4.0) の PowerShell を使用すると、次のように機能します。

PS> $repopath = "C:\path\to\localrepo"
PS> [SharpSvn.SvnUpdateResult]$update = $null
PS> $svnclient.Update([string]$repopath, [ref]$update)

ただし、これをオーバーロードの 1 つだけで動作させることができました!? 偶然かどうかはわかりませんが、$svnclient.Updateオーバーロードの定義を見ようと言ったときに最初に挙げられたオーバーロードです。

私のバージョンの PowerShell では、2 番目の引数を として指定する[ref][SharpSvn.SvnUpdateResult]$updateと、オーバーロードが正しく解決されたように見え、メソッドはエラーなしで実行されますが、"out" パラメーターに割り当てられたオブジェクトが失われるようです。

$repopathがタイプ セーフに として宣言されていても、(値渡しで) 渡すときにもう一度[string]$repopath = "C:\path\to\localrepo"言わなければならないようです。[string]$repopath

于 2015-06-04T11:23:54.057 に答える
1

これは理想的な解決策ではないかもしれませんが、Add-Type を使用して、Update メソッドをラップする、より PowerShell に適した型を作成できます。

Add-Type -TypeDefinition "
public class SvnClientEx
{
   public static SvnUpdateResult Update(SvnClient client, string path)
   {
       SvnUpdateResult result; 
       client.Update(path, out result);
       return result; 
   } 
}
"

$result = [SvnClient]::Update($svnClient, $repopath)
于 2012-12-23T20:05:39.750 に答える
0

コード ブロックを使用するだけで、このブロック内の結果 (out) オブジェクトにアクセスできます。

PS> $repopath = "C:\path\to\localrepo"
PS> $svnclient.update($repopath, { 
      Write-Host $_.Revision
      Write-Host $_.HasRevision
      # Access all the Member and Methods of the result object here
    })
于 2015-05-19T13:11:17.700 に答える