Azure PowerShell:“几乎无害”

图片6

大家好 今天,我们在测试中还有另一个Microsoft项目。 通过文章的标题,您可以猜测这次开发人员无法通过大量错误来取悦我们。 我们希望该名称的作者不会受到冒犯。 毕竟,少数错误是极好的,不是吗? 但是,在Azure PowerShell代码中发现了一些有趣的东西。 我们建议您熟悉该项目的功能,并查看PV#C分析仪PVS-Studio所发现的错误。

关于项目


Azure PowerShell是一个cmdlet,可让您直接从PowerShell命令行管理Azure资源。 该集合的主要目的是简化Azure的学习和开发的快速入门。 Azure PowerShell为管理员和开发人员提供了用于创建,部署和管理Microsoft Azure应用程序的强大功能。

Azure PowerShell在.NET Standard环境中开发,并且适用于Windows的PowerShell 5.1和适用于所有平台的PowerShell 6.x及更高版本。 GitHub上提供了Azure PowerShell 源代码

最近,Microsoft项目经常引起我的注意。 我认为这些项目的质量通常处于最佳状态。 当然,尽管并非没有例外,但文章“ WinForms:错误,福尔摩斯 ”也是如此。 但是,这次一切正常。 该项目很大:6845个.cs文件的源代码包含大约70万行,不包括空白(测试以及第三级可靠性的警告,我没有考虑在内)。 如此大量的代码很少有错误:不超过一百个。 有许多相同类型的情况,因此对于本文,我选择了最有趣的肯定。 正如我通常所做的那样,错误是通过PVS-Studio诊断编号进行排序的。

我还遇到了看起来像错误的代码片段,但是由于我对PowerShell的开发功能还不够熟悉,所以我无法对一个实际问题做出明确的结论。 我希望读者中将有这方面的专家,并将对我有所帮助。 关于它下面。

在“汇报”开始之前,我注意到该项目在结构上的特殊性。 Azure PowerShell源代码包含70多个Visual Studio解决方案。 一些解决方案包括其他解决方案中的项目。 这种结构使分析速度有所降低(不多)。 其余的验证没有造成困难。 为方便起见,在错误消息的行中(在括号中),我将指示检测到此错误的解决方案的名称。

验证结果


V3001在'||'的左侧和右侧有相同的子表达式'strTimespan.Contains(“ M”)'。 操作员。 AzureServiceBusCmdletBase.cs 187(事件网格)

public static TimeSpan ParseTimespan(string strTimespan) { .... if (strTimespan.Contains("P") || strTimespan.Contains("D") || strTimespan.Contains("T") || strTimespan.Contains("H") || strTimespan.Contains("M") || strTimespan.Contains("M")) .... } 

一个相当明显的错误的示例,只有开发人员才能解决。 在这种情况下,我们是要处理不影响任何代码的重复代码,还是应该在最后两个检查之一中代替“ M” ,这是完全无法理解的。

V3001在'&&'运算符的左侧和右侧有相同的子表达式'this.AggregationType!= Null'。 GetAzureRmMetricCommand.cs 156(监控器)

 public AggregationType? AggregationType { get; set; } .... protected override void ProcessRecordInternal() { .... string aggregation = (this.AggregationType != null && this.AggregationType.HasValue) ? this.AggregationType.Value.ToString() : null; .... } 

这里可能没有错误。 这是冗余代码的示例。 有时,此类代码可能表明开发人员知识水平不足。 事实是this.AggregationType!= Nullthis.AggregationType.HasValue检查是相同的。 使用其中之一(任意)就足够了。 就个人而言,我更喜欢HasValue选项

 string aggregation = this.AggregationType.HasValue ? this.AggregationType.Value.ToString() : null; 

V3003检测到使用'if(A){...} else if(A){...}'模式。 存在逻辑错误的可能性。 检查行:152,163。GetAzureRmRecoveryServicesBackupProtectionPolicy.cs 152(RecoveryServices)

 public override void ExecuteCmdlet() { .... if( WorkloadType == Models.WorkloadType.AzureVM ) { .... } .... else if( WorkloadType == Models.WorkloadType.AzureFiles ) { if( BackupManagementType != Models.BackupManagementType.AzureStorage ) { throw new ArgumentException( Resources.AzureFileUnsupportedBackupManagementTypeException ); } serviceClientProviderType = ServiceClientHelpers. GetServiceClientProviderType( Models.WorkloadType.AzureFiles ); } else if( WorkloadType == Models.WorkloadType.AzureFiles ) { if( BackupManagementType != Models.BackupManagementType.AzureStorage ) { throw new ArgumentException( Resources.AzureFileUnsupportedBackupManagementTypeException ); } serviceClientProviderType = ServiceClientHelpers. GetServiceClientProviderType( Models.WorkloadType.AzureFiles ); } .... } 

else两个if块绝对相同,包括块的条件和主体。 在工作中使用复制粘贴方法时,通常会发生此类错误。 再次的问题是此错误的严重性。 如果这不是简单的代码重复,那么我们可以谈谈缺少必要的验证和相应的操作集。 作者需要编辑代码。

V3005已将 “ this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent”变量分配给它自己。 SetAzureVMOperatingSystemCommand.cs 298(计算)

 public override void ExecuteCmdlet() { .... // OS Profile this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent = this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent; .... } 

该属性的值已分配给自身。 看一下他的广告:

 [JsonProperty(PropertyName = "provisionVMAgent")] public bool? ProvisionVMAgent { get; set; } 

JsonProperty描述说:“指示Newtonsoft.Json.JsonSerializer始终序列化具有指定名称的成员”。 似乎一切都很简单,并且有明显的错误。 同样令人困惑的是,此方法显式地使用来访问属性。 也许是由于错误而未指定其他变量来代替this 。 但是目前,我们不会得出结论。 事实是,在Azure PowerShell代码中,我遇到了很多此类分配(该属性已分配给自身)。 这是与错误非常相似的分配的另一个示例:

V3005将'this.LastHeartbeat'变量分配给它自己。 PSFabricDetails.cs 804(RecoveryServices)

 public ASRInMageAzureV2SpecificRPIDetails( InMageAzureV2ReplicationDetails details) { this.LastHeartbeat = this.LastHeartbeat; // <= this.RecoveryAvailabilitySetId = details.RecoveryAvailabilitySetId; this.AgentVersion = details.AgentVersion; this.DiscoveryType = details.DiscoveryType; .... } 

注意第二和以后的作业。 在表达式的右侧,根本没有出现,而是出现了细节 。 看一下this.LastHeartbeat属性的声明:

 public DateTime? LastHeartbeat { get; set; } 

最后,在InMageAzureV2ReplicationDetails类中查找具有相同名称的属性 。 在那里声明了这样的属性:

 public class InMageAzureV2ReplicationDetails : ReplicationProviderSpecificSettings { .... [JsonProperty(PropertyName = "lastHeartbeat")] public DateTime? LastHeartbeat { get; set; } .... } 

好吧,在这种情况下,我准备承认该操作是一个真正的错误。 但是,如何处理以下触发器? 在它们中,与前两个代码片段不同,它们具有多个属性分配。 这已经不像是一个错误:

  • V3005将'this.ResourceGroupName'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionCommand.cs 84(CognitiveServices)
  • V3005将'this.ExpressRouteGatewayName'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionConnectionCommand.cs 85(CognitiveServices)
  • V3005将'this.Name'变量分配给它自己。 RemoveAzureRmExpressRouteConnectionCommand.cs 86(CognitiveServices)

 [Cmdlet(VerbsCommon.Remove, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ExpressRouteConnection", DefaultParameterSetName = CortexParameterSetNames.ByExpressRouteConnectionName, SupportsShouldProcess = true), OutputType(typeof(bool))] public class RemoveExpressRouteConnectionCommand : ExpressRouteConnectionBaseCmdlet { [Parameter( Mandatory = true, ParameterSetName = CortexParameterSetNames.ByExpressRouteConnectionName, HelpMessage = "The resource group name.")] [ResourceGroupCompleter] [ValidateNotNullOrEmpty] public string ResourceGroupName { get; set; } .... public override void Execute() { if (....) { this.ResourceGroupName = this.ResourceGroupName; this.ExpressRouteGatewayName = this.ExpressRouteGatewayName; this.Name = this.Name; } .... } .... } 

Execute方法包含三个连续的属性分配给自己。 为了以防万一,我给出了RemoveExpressRouteConnectionCommandCommand类的完整声明及其所有属性,以及ResourceGroupName属性的声明(其他两个属性以相同的方式声明)。 正是这种触发使我想到了一个问题:“这是一个错误吗?” 我怀疑PowerShell开发会在某种程度上发生内部魔术。 我希望读者中有一些对此事有知识的专家。 我不准备在这种情况下下任何结论。

V3006已创建对象, 但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 259(RecoveryServices)

 private void StartRPITestFailover() { .... if (....) { .... } else { new ArgumentException( Resources .UnsupportedDirectionForTFO); // Throw Unsupported Direction // Exception } .... } 

跳过throw关键字。 而且,评论说应该抛出异常。 在RecoveryServices解决方案中,我遇到了更多类似的错误:

  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrTestFailoverJob.cs 305(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 278(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 StartAzureRmRecoveryServicesAsrUnPlannedFailover.cs 322(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 421(RecoveryServices)
  • V3006已创建对象,但未使用该对象。 可能没有'throw'关键字:throw new ArgumentException(FOO)。 UpdateAzureRmRecoveryServicesAsrProtectionDirection.cs 452(RecoveryServices)

V3022表达式“ apiType.HasValue”始终为false。 ApiManagementClient.cs 1134(ApiManagement)

 private string GetApiTypeForImport(...., PsApiManagementApiType? apiType) { .... if (apiType.HasValue) { switch(apiType.Value) { case PsApiManagementApiType.Http: return SoapApiType.SoapToRest; case PsApiManagementApiType.Soap: return SoapApiType.SoapPassThrough; default: return SoapApiType.SoapPassThrough; } } return apiType.HasValue ? // <= apiType.Value.ToString("g") : PsApiManagementApiType.Http.ToString("g"); } 

工作逻辑被违反。 如果apiType包含一个值,则控件将不会在方法末尾到达return表达式(所有switch分支均包含return )。 否则,该方法将始终分别返回PsApiManagementApiType.Http.ToString(“ g”)apiType.Value.ToString(“ g”)

V3022表达式'automationJob!= Null && automationJob == null'始终为false。 NodeConfigurationDeployment.cs 199(自动化)

 public NodeConfigurationDeployment( ...., Management.Automation.Models.Job automationJob = null, ....) { .... if (automationJob != null && automationJob == null) return; .... } 

矛盾的代码。 两项相互矛盾的检查。 可能第二个相等检查包含错误的变量。

V3022表达式始终为假。 DataFactoryClient.Encrypt.cs 37(DataFactory)

 public virtual string OnPremisesEncryptString(....) { .... if ( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService && linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService && linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService && (value == null || value.Length == 0)) { throw new ArgumentNullException("value"); } .... } 

检查是没有意义的,并且永远不会引发异常。 该条件需要将linkedServiceType变量同时等同三个不同的值。 &&和||运算符可能会混淆。 更正的代码:

 if (( linkedServiceType == LinkedServiceType.OnPremisesSqlLinkedService || linkedServiceType == LinkedServiceType.OnPremisesOracleLinkedService || linkedServiceType == LinkedServiceType.OnPremisesFileSystemLinkedService) && (value == null || value.Length == 0)) .... 

V3022表达式'Ekus == null'始终为false。 PSKeyVaultCertificatePolicy.cs 129(KeyVault)

 internal CertificatePolicy ToCertificatePolicy() { .... if (Ekus != null) { x509CertificateProperties.Ekus = Ekus == null ? null : new List<string>(Ekus); } .... } 

Ekus变量是否相等的多余检查。 可能没有错,但是代码看起来很丑。

V3023考虑检查此表达式。 表达式过多或打印错误。 PolicyRetentionObjects.cs 207(RecoveryServices)

 public virtual void Validate() { if (RetentionTimes == null || RetentionTimes.Count == 0 || RetentionTimes.Count != 1) { throw new ArgumentException( Resources.InvalidRetentionTimesInPolicyException); } } 

检查过多或状态错误。 检查RetentionTimes.Count == 0毫无意义,因为在那之后检查RetentionTimes.Count!= 1

V3025格式错误。 调用“格式”功能时,期望格式项目的数量不同。 未使用的参数:this.ResourceGroupName。 NewScheduledQueryRuleCommand.cs 117(监控器)

 protected override void ProcessRecordInternal() { .... if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {0}", this.Name, this.ResourceGroupName))) { .... } .... } 

格式字符串错误。 {0}限定符使用两次,两个参数传递给Format方法。 正确的选项:

 if (this.ShouldProcess(this.Name, string.Format("Creating Log Alert Rule '{0}' in resource group {1}", this.Name, this.ResourceGroupName))) .... 

另一个类似的错误:

  • V3025格式错误。 调用“格式”功能时,期望格式项目的数量不同。 未使用的参数:this.ResourceGroupName。 RemoveScheduledQueryRuleCommand.cs 88(监视器)

V3042可能为NullReferenceException。 '?。' 和“。” 运算符用于访问“ imageAndOsType”对象VirtualMachineScaleSetStrategy.cs 81(计算)的成员

 internal static ResourceConfig<VirtualMachineScaleSet> CreateVirtualMachineScaleSetConfig(...., ImageAndOsType imageAndOsType, ....) { .... VirtualMachineProfile = new VirtualMachineScaleSetVMProfile { OsProfile = new VirtualMachineScaleSetOSProfile { ...., WindowsConfiguration = imageAndOsType.CreateWindowsConfiguration(), // <= ...., }, StorageProfile = new VirtualMachineScaleSetStorageProfile { ImageReference = imageAndOsType?.Image, // <= DataDisks = DataDiskStrategy.CreateVmssDataDisks( imageAndOsType?.DataDiskLuns, dataDisks) // <= }, }, .... } 

创建VirtualMachineScaleSetVMProfile对象时,使用imageAndOsType变量而不检查null 。 但是,然后,在创建VirtualMachineScaleSetStorageProfile时 ,已使用条件访问运算符对该变量进行了两次检查。 该代码看起来不安全。

V3042可能为NullReferenceException。 '?。' 和“。” 运算符用于访问“ existingContacts”对象的成员RemoveAzureKeyVaultCertificateContact.cs 123(KeyVault)

 public override void ExecuteCmdlet() { .... List<PSKeyVaultCertificateContact> existingContacts; try { existingContacts = this.DataServiceClient. GetCertificateContacts(VaultName)?.ToList(); } catch (KeyVaultErrorException exception) { .... existingContacts = null; } foreach (var email in EmailAddress) { existingContacts.RemoveAll(....); // <= } .... } 

与正常执行的情况一样,由于处理了异常, 现存的Contacts变量可以为null ,之后将继续工作。 在代码中,此变量无需任何验证即可使用。

V3066传递给“ PersistSyncServerRegistration”方法的参数的可能错误顺序:“ storageSyncServiceUid”和“ discoveryUri”。 EcsManagementInteropClient.cs 364(StorageSync)

 public class EcsManagementInteropClient : IEcsManagement { .... public int PersistSyncServerRegistration(....) { return m_managementObject.PersistSyncServerRegistration( serviceUri, subscriptionId, storageSyncServiceName, resourceGroupName, clusterId, clusterName, storageSyncServiceUid, // <= discoveryUri, // <= serviceLocation, resourceLocation); } .... } 

分析器怀疑将参数传递给PersistSyncServerRegistration方法的顺序混乱 。 方法声明:

 public interface IEcsManagement : IDisposable { .... int PersistSyncServerRegistration( [In, MarshalAs(UnmanagedType.BStr)] string serviceUri, [In, MarshalAs(UnmanagedType.BStr)] string subscriptionId, [In, MarshalAs(UnmanagedType.BStr)] string storageSyncServiceName, [In, MarshalAs(UnmanagedType.BStr)] string resourceGroupName, [In, MarshalAs(UnmanagedType.BStr)] string clusterId, [In, MarshalAs(UnmanagedType.BStr)] string clusterName, [In, MarshalAs(UnmanagedType.BStr)] string discoveryUri, // <= [In, MarshalAs(UnmanagedType.BStr)] string storageSyncServiceUid, // <= [In, MarshalAs(UnmanagedType.BStr)] string serviceLocation, [In, MarshalAs(UnmanagedType.BStr)] string resourceLocation); .... } 

确实,这里有些东西与参数7和8混在一起。 作者需要验证代码。

V3077 “ GetGuid”属性的设置器未使用其“值”参数。 RecoveryServicesBackupCmdletBase.cs 54(RecoveryServices)

 public abstract class RecoveryServicesBackupCmdletBase : AzureRMCmdlet { .... static string _guid; protected static string GetGuid { get { return _guid; } set { _guid = Guid.NewGuid().ToString(); } } .... } 

设置器不使用传输的参数。 相反,他们获得了一个新的GUID,并将其分配给_guid字段。 我认为大多数读者都会同意这样的代码看起来至少很难看。 使用这样的构造不是很方便:要(重新)初始化GetGuid属性,必须为它分配一些假值,这是完全不明显的。 但是,当作者自己如何使用这种构造的那一刻,我感到最开心的是。 在代码中,只有一个地方可以使用GetGuid 。 看一下:

 public override void ExecuteCmdlet() { .... var itemResponse = ServiceClientAdapter.CreateOrUpdateProtectionIntent( GetGuid ?? Guid.NewGuid().ToString(), ....); .... } 

太好了!

V3091实证分析。 字符串文字中可能存在拼写错误:“管理组ID”。 “ Id”一词可疑。 Constants.cs 36(资源)

 public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id"; // <= public const string Recurse = "Recursively list the children of the management group"; public const string ParentId = "Parent Id of the management group"; public const string GroupName = "Management Group Id"; // <= public const string DisplayName = "Display Name of the management group"; public const string Expand = "Expand the output to list the children of the management group"; public const string Force = "Force the action and skip confirmations"; public const string InputObject = "Input Object from the Get call"; public const string ParentObject = "Parent Object"; } 

分析器在为GroupName常量分配的字符串中指示可能的错误。 结论是基于对其他分配的实证分析,并考虑了变量名。 我认为在这种情况下,分析器是正确的, GroupName常量的值应为“ Management Group name”。 该错误可能是由于复制GroupId常量的值而导致的,但是他们忘记更改了它。

另一个类似的错误:

  • V3091实证分析。 字符串文字中可能存在错字。 “名称”一词可疑。 ParamHelpMsgs.cs 153(RecoveryServices)

V3093 '|' 运算符同时计算两个操作数。 也许是短路“ ||” 应该使用运算符代替。 PSKeyVaultCertificatePolicy.cs 114(KeyVault)

 internal CertificatePolicy ToCertificatePolicy() { .... if (!string.IsNullOrWhiteSpace(SubjectName) || DnsNames != null || Ekus != null || KeyUsage != null | // <= ValidityInMonths.HasValue) { .... } .... } 

有人怀疑发生了错误,并且在if块的最后一个条件之间也应使用||运算符。 经常发生的确切答案只能由开发人员提供。

V3095在对null进行验证之前,已使用“证书”对象。 检查行:41,43。CertificateInfo.cs 41(自动化)

 public CertificateInfo( ...., Azure.Management.Automation.Models.Certificate certificate) { .... this.Name = certificate.Name; if (certificate == null) return; .... } 

经典版 首先使用该对象,然后才检查该链接是否为null 。 我们经常遇到这样的错误。 考虑另一个类似的错误。

V3095在对null进行验证之前,已使用'clusterCred'对象。 检查行:115、118。InvokeHiveCommand.cs 115(HDInsight)

 public override void ExecuteCmdlet() { .... _credential = new BasicAuthenticationCloudCredentials { Username = clusterCred.UserName, Password = clusterCred.Password.ConvertToString() }; if (clusterConnection == null || clusterCred == null) .... } 

还有更多类似的错误:

  • V3095在验证是否为null之前,已使用'_profile'对象。 检查行:47,49。RMProfileClient.cs 47(帐户)
  • V3095在对null进行验证之前,已使用'this.LoadBalancer.BackendAddressPools'对象。 检查行:56,63。AddAzureRmLoadBalancerBackendAddressPoolConfigCommand.cs 56(CognitiveServices)
  • 通常,在Azure PowerShell代码中,我遇到了很多V3095错误。 但是它们都非常相似,因此我将不作更详细的介绍。

V3125在验证了null之后使用了“ startTime”对象。 检查行:1752、1738。AutomationPSClientDSC.cs 1752(自动化)

 private string GetNodeReportListFilterString( ...., DateTimeOffset? startTime, ...., DateTimeOffset? lastModifiedTime) { .... if (startTime.HasValue) { odataFilter.Add("properties/startTime ge " + this.FormatDateTime(startTime.Value)); // <= } .... if (lastModifiedTime.HasValue) { odataFilter.Add("properties/lastModifiedTime ge " + this.FormatDateTime(startTime.Value)); // <= } .... } 

这也是一种相当常见的错误类型。 首次使用时检查了startTime变量的值。 下次使用时,请不要使用。 但是情况可能更糟。 看一下第二个if块。 我认为根本不应该有一个startTime变量。 这可以通过在使用前不检查其值是否存在以及为传递给Add方法而形成的字符串来表明。 该行的第一部分提到另一个变量( lastModifiedTime )。

V3125在验证了null之后使用了“ firstPage”对象。 检查行:113、108。IntegrationAccountAgreementOperations.cs 113(LogicApp)

 public IList<IntegrationAccountAgreement> ListIntegrationAccountAgreements(....) { var compositeList = new List<IntegrationAccountAgreement>(); var firstPage = this.LogicManagementClient. IntegrationAccountAgreements.List(....); if (firstPage != null) { compositeList.AddRange(firstPage); } if (!string.IsNullOrEmpty(firstPage.NextPageLink)) // <= { .... } .... } 

另一个明显的错误。 变量firstPage的使用不安全,尽管在代码的较早版本中,已将此变量与对null的初步检查一起使用。

Azure PowerShell代码中的V3125之前描述的V3095成功 。 它们也都是同一类型。 我认为我们可以将自己限制在我们所研究的两个方面。

V3137分配了'apiVersionSetId'变量,但未在函数末尾使用。 GetAzureApiManagementApiVersionSet.cs 69(ApiManagement)

 public String ApiVersionSetId { get; set; } .... public override void ExecuteApiManagementCmdlet() { .... string apiVersionSetId; if (ParameterSetName.Equals(ContextParameterSet)) { .... apiVersionSetId = ApiVersionSetId; } else { apiVersionSetId = ....; } if (string.IsNullOrEmpty(ApiVersionSetId)) // <= { WriteObject(....); } else { WriteObject(Client.GetApiVersionSet(...., ApiVersionSetId)) // <= } } 

分析器报告本地变量apiVersionSetId已初始化,但尚未使用。 通常,这种模式表示错误。 考虑到局部变量apiVersionSetId的名称和属性ApiVersionSetId的名称仅在首字母不同的情况下,我认为在这种情况下出错的可能性很高。 看一下代码。 初始化apiVersionSetId (以一种或另一种方式)后,在代码中仅使用ApiVersionSetId属性。 非常非常可疑。

V3137分配了'cacheId'变量,但在函数末尾未使用该变量。 RemoveAzureApiManagementCache.cs 94(ApiManagement)

 public String CacheId { get; set; } .... public override void ExecuteApiManagementCmdlet() { .... string cacheId; if (....) { .... cacheId = InputObject.CacheId; } else if (....) { .... cacheId = cache.CacheId; } else { .... cacheId = CacheId; } var actionDescription = string.Format(...., CacheId); // <= var actionWarning = string.Format(...., CacheId); // <= .... Client.CacheRemove(resourceGroupName, serviceName, CacheId); // <= .... } 

这种情况几乎完全重复了先前考虑的情况。 初始化后不使用局部变量cacheId 。 而是使用名称非常相似的属性CacheId 。 我不知道,也许在Azure PowerShell开发人员中就是这种模式。 但这似乎是一个错误。

V3143 '值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountPartnerCommand.cs 67(LogicApp)

 [Parameter(Mandatory = false, HelpMessage = "The integration account partner type.", ValueFromPipelineByPropertyName = false)] [ValidateSet("B2B", IgnoreCase = false)] [ValidateNotNullOrEmpty] public string PartnerType { get { return this.partnerType; } set { value = this.partnerType; } // <= } 

partnerType字段声明如下:

 /// <summary> /// Default partner type. /// </summary> private string partnerType = "B2B"; 

与检测到此错误的解决方案的名称(LogicApp)相反,我在这里看不到逻辑。 在设置器中使用进行记录的情况并不罕见,但是在这种情况下,我们正在谈论丢失原始值。 看起来很奇怪。 该代码对该属性具有单个读取访问权限。 也许您应该再次寻求专家的建议。 也许我听不懂。 事实是,我遇到了更多完全相同的模式:

  • V3143'值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountSchemaCommand.cs 79(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 NewAzureIntegrationAccountSchemaCommand.cs 87(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountPartnerCommand.cs 67(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountSchemaCommand.cs 80(LogicApp)
  • V3143'值'参数在属性设置器中重写,此后不再使用。 UpdateAzureIntegrationAccountSchemaCommand.cs 88(LogicApp)

结论


这就是在Azure PowerShell代码中发现的所有有趣的错误。 热心者和有兴趣的人,我建议对这个(或任何其他)项目的代码中的错误进行独立研究。我可能会错过其他有趣的事情。为此,只需下载并安装PVS-Studio即可

感谢您的阅读。无代码的代码!



如果您想与说英语的读者分享这篇文章,请使用以下链接:Sergey Khrenov。 Azure PowerShell:几乎无害

Source: https://habr.com/ru/post/zh-CN470730/


All Articles