.net - Powershell 4 中重载的方法解析错误
问题描述
我正在尝试TfvcHttpClient.GetItemsAsync()
从 Powershell 脚本调用:
$Full = [Microsoft.TeamFoundation.SourceControl.WebApi.VersionControlRecursionType]::Full
$None = [System.Threading.CancellationToken]::None
$Items = $Cli.GetItemsAsync($TFVCPath, $Full, $false, $null, $null, $None).GetAwaiter().GetResult()
在 Powershell 4 中,它会出错:
##[error]System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Management.Automation.Adapter.CompareOverloadCandidates(OverloadCandidate candidate1, OverloadCandidate candidate2, Object[] arguments)
at System.Management.Automation.Adapter.FindBestCandidate(IEnumerable`1 candidates, Object[] arguments)
at System.Management.Automation.Adapter.FindBestCandidate(IEnumerable`1 candidates, Object[] arguments, PSMethodInvocationConstraints invocationConstraints)
at System.Management.Automation.Adapter.FindBestMethod(MethodInformation[] methods, PSMethodInvocationConstraints invocationConstraints, Object[] arguments, String& errorId, String& errorMsg, Boolean& expandParamsOnBest)
at System.Management.Automation.Language.PSInvokeMemberBinder.InvokeDotNetMethod(DynamicMetaObject target, DynamicMetaObject[] args, BindingRestrictions restrictions, MethodInformation[] mi, Type errorExceptionType)
at System.Management.Automation.Language.PSInvokeMemberBinder.FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
at System.Dynamic.DynamicMetaObject.BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
at System.Dynamic.UpdateDelegates.UpdateAndExecute7[T0,T1,T2,T3,T4,T5,T6,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
at System.Management.Automation.Interpreter.DynamicInstruction``8.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
看起来重载解析的逻辑是错误的。该方法确实是重载的,但只有一个重载有 6 个参数。另外两个有7个。
Powershell 4 支持使用默认值省略方法参数(只要它们是null
),因此重载解析逻辑仍然可能适用。但是,我的调用并不模棱两可——没有其他重载将 aVersionControlRecursionType
作为第二个参数。
任何想法如何解决这个问题?也许有一种方法可以告诉 Powershell 调用特定的重载?
他们已经在 PS5 中修复了这个问题,但仍然......
编辑:在干净的 DLL 上复制。这是 DLL 代码,再现了有问题的方法签名:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.TeamFoundation.SourceControl.WebApi
{
public enum VersionControlRecursionType
{
None = 0, OneLevel = 1, OneLevelPlusNestedEmptyFolders = 4, Full = 120
}
public class TfvcItem { }
public class TfvcVersionDescriptor { }
public abstract class TfvcHttpClientBase
{
public TfvcHttpClientBase() { }
public virtual Task<List<TfvcItem>> GetItemsAsync(string project, string scopePath = null, VersionControlRecursionType? recursionLevel = null, bool? includeLinks = null, TfvcVersionDescriptor versionDescriptor = null, object userState = null, CancellationToken cancellationToken = default(CancellationToken))
{
return null;
}
public virtual Task<List<TfvcItem>> GetItemsAsync(Guid project, string scopePath = null, VersionControlRecursionType? recursionLevel = null, bool? includeLinks = null, TfvcVersionDescriptor versionDescriptor = null, object userState = null, CancellationToken cancellationToken = default(CancellationToken))
{
return null;
}
public virtual Task<List<TfvcItem>> GetItemsAsync(string scopePath = null, VersionControlRecursionType? recursionLevel = null, bool? includeLinks = null, TfvcVersionDescriptor versionDescriptor = null, object userState = null, CancellationToken cancellationToken = default(CancellationToken))
{
return null;
}
}
public class TfvcHttpClient : TfvcHttpClientBase
{
public TfvcHttpClient() { }
}
}
这是演示该行为的 Powershell:
Add-Type -Path "Foo.dll"
$Cli = New-Object Microsoft.TeamFoundation.SourceControl.WebApi.TfvcHttpClient
$Full = [Microsoft.TeamFoundation.SourceControl.WebApi.VersionControlRecursionType]::Full
$None = [System.Threading.CancellationToken]::None
$Items = $Cli.GetItemsAsync("", $Full, $false, $null, $null, $None)
我也在调试器中发现了异常。冒犯的方法位于System.Management.Automation.dll
. 描述重载方法的candidate
参数包含两个数组 -arguments
和conversionRanks
. 代码期望它们具有相同的长度,但前者有 7 个元素,后者有 6 个。
解决方案
将 GUID 作为第一个参数的 7 参数方法重载不会以这种特定方式出错。Powershell 4 仍然有一个方法解析错误 :)
推荐阅读
- python-3.x - How to delete rows in Dataframe that contain attribute values in Series
- angular - How to return observable in observable map in Angular
- r - 有没有办法摆脱 R 中某个字符串之前和之后的行(基于从 excel 导入的数据)?
- google-sheets - IFTTT doesn't trigger on new row for Google Sheets service
- javascript - 如何制作类似于 nodebb 的 AJAX 应用程序?
- apache-kafka - 处理大型 Kafka 主题
- php - 如果数组中的一个值在PHP中为空,如何跳过一个动作并继续前进
- r - 分组依据和条件摘要
- c++ - 在不损失质量的情况下显示图像
- ruby - 在 Ruby 中调用 PostGIS 函数