From a608769ebf5e1cfb479c5e4c561cdfeec3468f62 Mon Sep 17 00:00:00 2001 From: James May Date: Mon, 8 Nov 2021 11:52:43 +1100 Subject: [PATCH 1/7] New Analyzer: Do not call Enumerable.Cast or Enumerable.OfType ith incompatible types --- .../Core/AnalyzerReleases.Unshipped.md | 1 + .../MicrosoftNetCoreAnalyzersResources.resx | 15 + ...stOrOfTypeWithIncompatibleTypesAnalyzer.cs | 316 ++++++++ .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 41 + .../MicrosoftNetCoreAnalyzersResources.it.xlf | 41 + .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 41 + .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 41 + .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 41 + ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 41 + .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 41 + .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 41 + ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 41 + ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 41 + .../Microsoft.CodeAnalysis.NetAnalyzers.md | 18 + .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 20 + src/NetAnalyzers/RulesMissingDocumentation.md | 1 + ...fTypeWithIncompatibleTypesAnalyzerTests.cs | 723 ++++++++++++++++++ 17 files changed, 1504 insertions(+) create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index 3f1647c0f9..b17217c892 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -12,6 +12,7 @@ CA1856 | Performance | Error | ConstantExpectedAnalyzer, [Documentation](https:/ CA1857 | Performance | Warning | ConstantExpectedAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1857) CA1858 | Performance | Info | UseStartsWithInsteadOfIndexOfComparisonWithZero, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1858) CA1859 | Performance | Info | UseConcreteTypeAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859) +CA2021 | Reliability | Warning | DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021) ### Removed Rules diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index c85a352e35..7383be62bc 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1008,6 +1008,12 @@ When creating path for '{0} in method {1}' from relative archive item path to extract file and the source is an untrusted zip archive, make sure to sanitize relative archive item path '{2} in method {3}' + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + Do not create tasks without passing a TaskScheduler @@ -1722,6 +1728,15 @@ The 'ModuleInitializer' attribute should not be used in libraries + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + '{0}' synchronously blocks. Await '{1}' instead. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs new file mode 100644 index 0000000000..4272e672a4 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs @@ -0,0 +1,316 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Linq; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +namespace Microsoft.NetCore.Analyzers.Runtime +{ + /// + /// CA2021: Do not call Enumerable.Cast or Enumerable.OfType with incompatible types. + /// + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer : DiagnosticAnalyzer + { + internal const string RuleId = "CA2021"; + + private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + + private static readonly LocalizableString s_localizableCastMessage = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesMessageCast), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableOfTypeMessage = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesMessageOfType), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + + internal static DiagnosticDescriptor CastRule = DiagnosticDescriptorHelper.Create(RuleId, + s_localizableTitle, + s_localizableCastMessage, + DiagnosticCategory.Reliability, + RuleLevel.BuildWarning, + s_localizableDescription, + isPortedFxCopRule: false, + isDataflowRule: false); + + internal static DiagnosticDescriptor OfTypeRule = DiagnosticDescriptorHelper.Create(RuleId, + s_localizableTitle, + s_localizableOfTypeMessage, + DiagnosticCategory.Reliability, + RuleLevel.BuildWarning, + s_localizableDescription, + isPortedFxCopRule: false, + isDataflowRule: false); + + private static readonly ImmutableArray<(string MethodName, DiagnosticDescriptor Rule)> s_methodMetadataNames = ImmutableArray.Create( + (nameof(Enumerable.Cast), CastRule), + (nameof(Enumerable.OfType), OfTypeRule) + ); + + public override ImmutableArray SupportedDiagnostics + => ImmutableArray.Create(OfTypeRule, CastRule); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + + context.RegisterCompilationStartAction(context => + { + if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemLinqEnumerable, out var enumerableType)) + { + return; + } + + var methodRuleDictionary = s_methodMetadataNames + .SelectMany(m => enumerableType + .GetMembers(m.MethodName) + .OfType() + .Where(method => method.IsExtensionMethod + && method.TypeParameters.HasExactly(1) + && method.Parameters.HasExactly(1) + && method.Parameters[0].Type.OriginalDefinition.SpecialType + == SpecialType.System_Collections_IEnumerable + ) + .Select(method => (method, m.Rule))) + .ToImmutableDictionary(key => key.method, v => v.Rule, SymbolEqualityComparer.Default); + + if (methodRuleDictionary.IsEmpty) + { + return; + } + + context.RegisterOperationAction(context => + { + var invocation = (IInvocationOperation)context.Operation; + + var targetMethod = (invocation.TargetMethod.ReducedFrom ?? invocation.TargetMethod).OriginalDefinition; + + if (!methodRuleDictionary.TryGetValue(targetMethod, out var rule)) + { + return; + } + + var instanceArg = invocation.GetInstance(); // "this" argument of an extension method + + static ITypeSymbol? GetIEnumerableTParam(ITypeSymbol type) + { + if (type is not INamedTypeSymbol argIEnumerableType + || !argIEnumerableType.TypeArguments.HasExactly(1)) + { + return null; + } + + return argIEnumerableType.TypeArguments[0]; + } + + static ITypeSymbol? FindElementType(IOperation? operation) + { + if (operation is null) + { + return null; + } + + if (operation.Kind == OperationKind.ArrayCreation) + { + return (operation.Type as IArrayTypeSymbol)?.ElementType; + } + + if (operation.Type?.OriginalDefinition?.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T) + { + return GetIEnumerableTParam(operation.Type); + } + + var r = operation?.Type?.AllInterfaces.FirstOrDefault(t => t.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T); + if (r is not null) + { + return GetIEnumerableTParam(r); + } + + if (operation is IParenthesizedOperation parenthesizedOperation) + { + return FindElementType(parenthesizedOperation.Operand); + } + + if (operation is IConversionOperation conversionOperation + && conversionOperation.OperatorMethod is null) // implicit meaning 'not user defined' + { + return FindElementType(conversionOperation.Operand); + } + + return null; + } + + // because the type of the parameter is actually the non-generic IEnumerable, + // we have to reach back through conversion operator(s) to get the element type + var castFrom = FindElementType(instanceArg); + if (castFrom is null) + { + return; + } + + if (!invocation.TargetMethod.TypeArguments.HasExactly(1)) + { + return; + } + + var castTo = invocation.TargetMethod.TypeArguments[0]; + + if (CastWillAlwaysFail(castFrom, castTo)) + { + context.ReportDiagnostic(invocation.CreateDiagnostic(rule, castFrom.ToDisplayString(), castTo.ToDisplayString())); + } + }, OperationKind.Invocation); + }); + + // because this is a warning, we want to be very sure + // this won't catch all problems, but it should never report something + // as a problem in correctly. We don't want another IDE0004 + static bool CastWillAlwaysFail(ITypeSymbol castFrom, ITypeSymbol castTo) + { + if (castFrom.TypeKind == TypeKind.Error + || castTo.TypeKind == TypeKind.Error) + { + return false; + } + + if (castFrom.SpecialType == SpecialType.System_Object + || castTo.SpecialType == SpecialType.System_Object) + { + // some things will actually fail, eg. TypedReference + // but they should be pretty rare + return false; + } + + if (castFrom.Equals(castTo, SymbolEqualityComparer.Default)) + { + return false; + } + + static ITypeSymbol UnwrapNullableValueType(ITypeSymbol typeSymbol) + { + if (typeSymbol.IsValueType + && typeSymbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T + && ((INamedTypeSymbol)typeSymbol).TypeArguments[0] is var nullableTypeArgument) + { + return nullableTypeArgument; + } + return typeSymbol; + } + + castFrom = UnwrapNullableValueType(castFrom); + castTo = UnwrapNullableValueType(castTo); + + static bool IsUnconstrainedTypeParameter(ITypeParameterSymbol typeParameterSymbol) + => !typeParameterSymbol.HasValueTypeConstraint + && typeParameterSymbol.ConstraintTypes.IsEmpty; + // because object is a reference type the 'class' reference type constraint + // doesn't actually constrain unless a type is specified too + // not implemented: + // NotNullConstraint + // ConstructorConstraint + // UnmanagedTypeConstraint + // Nullability annotations + + switch (castFrom.OriginalDefinition.TypeKind, castTo.OriginalDefinition.TypeKind) + { + case (TypeKind.TypeParameter, _): + var castFromTypeParam = (ITypeParameterSymbol)castFrom.OriginalDefinition; + if (IsUnconstrainedTypeParameter(castFromTypeParam)) + { + return false; + } + + if (castFromTypeParam.ConstraintTypes.Any(constraintType => CastWillAlwaysFail(constraintType, castTo))) + { + return true; + } + + if (castFromTypeParam.HasValueTypeConstraint + && castTo.TypeKind == TypeKind.Class) + { + return true; + } + return false; + case (_, TypeKind.TypeParameter): + var castToTypeParam = (ITypeParameterSymbol)castTo.OriginalDefinition; + if (IsUnconstrainedTypeParameter(castToTypeParam)) + { + return false; + } + + if (castToTypeParam.ConstraintTypes.Any(constraintType => CastWillAlwaysFail(castFrom, constraintType))) + { + return true; + } + + if (castToTypeParam.HasValueTypeConstraint + && castFrom.TypeKind == TypeKind.Class) + { + return true; + } + return false; + + case (TypeKind.Class, TypeKind.Class): + return !castFrom.DerivesFrom(castTo) + && !castTo.DerivesFrom(castFrom); + + case (TypeKind.Interface, TypeKind.Class): + return castTo.IsSealed && !castTo.AllInterfaces.Contains(castFrom); + case (TypeKind.Class, TypeKind.Interface): + return castFrom.IsSealed && !castFrom.AllInterfaces.Contains(castTo); + + case (TypeKind.Class, TypeKind.Enum): + return castFrom.OriginalDefinition.SpecialType != SpecialType.System_Enum + && castFrom.OriginalDefinition.SpecialType != SpecialType.System_ValueType; + case (TypeKind.Enum, TypeKind.Class): + return castTo.OriginalDefinition.SpecialType != SpecialType.System_Enum + && castTo.OriginalDefinition.SpecialType != SpecialType.System_ValueType; + + case (TypeKind.Struct, TypeKind.Enum) + when castTo.OriginalDefinition is INamedTypeSymbol toEnum: + return !castFrom.Equals(toEnum.EnumUnderlyingType); + case (TypeKind.Enum, TypeKind.Struct) + when castFrom.OriginalDefinition is INamedTypeSymbol fromEnum: + return !fromEnum.EnumUnderlyingType.Equals(castTo); + + case (TypeKind.Enum, TypeKind.Enum) + when castFrom.OriginalDefinition is INamedTypeSymbol fromEnum + && castTo.OriginalDefinition is INamedTypeSymbol toEnum: + return !fromEnum.EnumUnderlyingType.Equals(toEnum.EnumUnderlyingType); + + // this is too conservative + // array variance is not implemented + // - eg. object[] -> class[] + // boxing shouldn't be allowed + // - eg. object[] -> ValueType[] + case (TypeKind.Array, TypeKind.Array) + when castFrom is IArrayTypeSymbol fromArray + && castTo is IArrayTypeSymbol toArray: + return fromArray.Rank != toArray.Rank + || CastWillAlwaysFail(fromArray.ElementType, toArray.ElementType); + + case (TypeKind.Array, TypeKind.Class): + return castTo.OriginalDefinition.SpecialType != SpecialType.System_Array; + case (TypeKind.Class, TypeKind.Array): + return castFrom.OriginalDefinition.SpecialType != SpecialType.System_Array; + + case (TypeKind.Class, TypeKind.Struct): + return castFrom.OriginalDefinition.SpecialType != SpecialType.System_ValueType; + case (TypeKind.Struct, TypeKind.Class): + return castTo.OriginalDefinition.SpecialType != SpecialType.System_ValueType; + + case (_, TypeKind.Enum): + case (TypeKind.Enum, _): + case (_, TypeKind.Struct): + case (TypeKind.Struct, _): + return true; + + case (TypeKind.Interface, TypeKind.Interface): + default: + return false; // we don't *know* it'll fail... + } + } + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index e6ff2c982b..3a9b3870e7 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -552,6 +552,47 @@ Při deserializaci instance třídy {0} může metoda {1} volat nebezpečnou metodu {2}. Možná volání metod: {3} + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + Když konstruktor zavolá virtuální metodu, konstruktor dané instance, která metodu vyvolala, se nemusí spustit. + + + + Do not call overridable methods in constructors + Nevolejte přepsatelné metody v konstruktorech + + + + Do not call overridable methods in constructors + Nevolejte přepsatelné metody v konstruktorech + + Do not call {0} on an {1} value Nevolejte {0} pro hodnotu {1}. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index 7fd7be09e7..41f5e6d670 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -552,6 +552,47 @@ Durante la deserializzazione di un'istanza della classe {0} il metodo {1} può chiamare il metodo pericoloso {2}. Le potenziali chiamate al metodo sono: {3}. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + Quando un costruttore chiama un metodo virtuale, è possibile che il costruttore per l'istanza che richiama il metodo non sia stato eseguito. + + + + Do not call overridable methods in constructors + Non chiamare metodi sottoponibili a override nei costruttori + + + + Do not call overridable methods in constructors + Non chiamare metodi sottoponibili a override nei costruttori + + Do not call {0} on an {1} value Non chiamare {0} su un valore {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index 3c247c71a0..ee0ec64aa7 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -552,6 +552,47 @@ クラス {0} のインスタンスを逆シリアル化すると、メソッド {1} によって危険なメソッド {2} を呼び出されるおそれがあります。考えられるメソッド呼び出し: {3}。 + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + コンストラクターが仮想メソッドを呼び出すときに、メソッドを呼び出すインスタンスのコンストラクターは実行されていない可能性があります。 + + + + Do not call overridable methods in constructors + コンストラクターのオーバーライド可能なメソッドを呼び出しません + + + + Do not call overridable methods in constructors + コンストラクターのオーバーライド可能なメソッドを呼び出しません + + Do not call {0} on an {1} value {1} 値で {0} を呼び出さないでください diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 05c4a1acfb..27a435f256 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -552,6 +552,47 @@ {0} 클래스의 인스턴스를 역직렬화할 때 {1} 메서드가 위험한 메서드 {2}을(를) 호출할 수 있습니다. 잠재적인 메서드 호출은 {3}입니다. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + 생성자에서 가상 메서드를 호출하면 메서드를 호출하는 인스턴스에 대한 생성자가 실행되지 않을 수 있습니다. + + + + Do not call overridable methods in constructors + 생성자에서 재정의 가능한 메서드를 호출하지 마세요. + + + + Do not call overridable methods in constructors + 생성자에서 재정의 가능한 메서드를 호출하지 마세요. + + Do not call {0} on an {1} value {1} 값의 {0}을(를) 호출하지 마세요. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index 4bcdb95650..fdaf3f0db9 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -552,6 +552,47 @@ Podczas deserializacji wystąpienia klasy {0} metoda {1} może wywołać niebezpieczną metodę {2}. Potencjalne wywołania metod to: {3}. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + Gdy konstruktor wywołuje metodę wirtualną, konstruktor wystąpienia wywołującego metodę może nie zostać wykonany. + + + + Do not call overridable methods in constructors + Nie wywołuj w konstruktorach metod, które można przesłaniać + + + + Do not call overridable methods in constructors + Nie wywołuj w konstruktorach metod, które można przesłaniać + + Do not call {0} on an {1} value Nie wywołuj elementu {0} dla wartości {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index 4d4378a30f..6018910c76 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -552,6 +552,47 @@ Ao desserializar uma instância da classe {0}, o método {1} pode chamar o método perigoso {2}. As possíveis invocações de método são: {3}. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + Quando um construtor chama um método virtual, o construtor para a instância que invoca o método pode não ter sido executado. + + + + Do not call overridable methods in constructors + Não chamar métodos substituíveis em construtores + + + + Do not call overridable methods in constructors + Não chamar métodos substituíveis em construtores + + Do not call {0} on an {1} value Não chamar {0} em um valor {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index 02e39eff91..863da7fb53 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -552,6 +552,47 @@ При десериализации экземпляра класса {0} метод {1} может вызывать опасный метод {2}. Потенциальные вызовы методов: {3}. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + Когда конструктор вызывает виртуальный метод, конструктор может не выполняться для экземпляра, вызывающего этот метод. + + + + Do not call overridable methods in constructors + Не вызывайте переопределяемые методы в конструкторах + + + + Do not call overridable methods in constructors + Не вызывайте переопределяемые методы в конструкторах + + Do not call {0} on an {1} value Не вызывайте {0} для значения {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index 0e36e36d41..327a478a76 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -552,6 +552,47 @@ {0} sınıfının bir örneği seri durumdan çıkarılırken, {1} metodu tehlikeli {2} metodunu çağırabilir. Olası metot çağırmaları: {3}. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + Bir oluşturucu tarafından sanal bir yöntem çağrıldığında, yöntemi tetikleyen örneğin oluşturucusu yürütülmemiş olabilir. + + + + Do not call overridable methods in constructors + Oluşturucularda geçersiz kılınabilen yöntemleri çağırmayın + + + + Do not call overridable methods in constructors + Oluşturucularda geçersiz kılınabilen yöntemleri çağırmayın + + Do not call {0} on an {1} value Bir {1} değeri üzerinde {0} çağırmayın diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index d1a5f5ed81..71fc63a7bd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -552,6 +552,47 @@ 反序列化类 {0} 的实例时,方法 {1} 可调用危险方法 {2}。潜在的方法调用为: {3}。 + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + 构造函数调用虚方法时,可能尚未执行调用该方法的实例的构造函数。 + + + + Do not call overridable methods in constructors + 不要在构造函数中调用可重写的方法 + + + + Do not call overridable methods in constructors + 不要在构造函数中调用可重写的方法 + + Do not call {0} on an {1} value 请勿对 {1} 值调用 {0} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index ce726ca18f..f81c59ec82 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -552,6 +552,47 @@ 將類別 {0} 的執行個體還原序列化時,方法 {1} 可以呼叫危險的方法 {2}。潛在的方法引動過程為: {3}。 + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + + + When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. + 當建構函式呼叫虛擬方法時,可能尚未執行叫用方法之執行個體的建構函式。 + + + + Do not call overridable methods in constructors + 請勿呼叫建構函式中的可覆寫方法 + + + + Do not call overridable methods in constructors + 請勿呼叫建構函式中的可覆寫方法 + + Do not call {0} on an {1} value 請勿對 {1} 值呼叫 {0} diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 29d6af40b3..8701baf5de 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -1860,6 +1860,24 @@ Some built-in operators added in .NET 7 behave differently when overflowing than |CodeFix|False| --- +## [CA2021](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2019): Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types + +Enumerable.Cast\ and Enumerable.OfType\ require compatible types to function expectedly. + +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast\ will throw InvalidCastException at runtime on elements of the types specified. + +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType\ will never succeed with elements of types specified, resulting in an empty sequence. + +Widening and user defined conversions are not supported with generic types. + +|Item|Value| +|-|-| +|Category|Reliability| +|Enabled|True| +|Severity|Warning| +|CodeFix|False| +--- + ## [CA2100](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2100): Review SQL queries for security vulnerabilities SQL queries that directly use user input can be vulnerable to SQL injection attacks. Review this SQL query for potential vulnerabilities, and consider using a parameterized SQL query. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 416275fda2..8d1441983b 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -3358,6 +3358,26 @@ ] } }, + "CA2021": { + "id": "CA2021", + "shortDescription": "Do not call Enumerable.Cast or Enumerable.OfType with incompatible types", + "fullDescription": "Enumerable.Cast and Enumerable.OfType require compatible types to function expectedly. \u000aThe generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast will throw InvalidCastException at runtime on elements of the types specified. \u000aThe generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType will never succeed with elements of types specified, resulting in an empty sequence. \u000aWidening and user defined conversions are not supported with generic types.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA2100": { "id": "CA2100", "shortDescription": "Review SQL queries for security vulnerabilities", diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index 7325b31a64..c37e954e76 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -12,3 +12,4 @@ CA1856 | | A constant is expected for the parameter | CA1858 | | Use 'StartsWith' instead of 'IndexOf' | CA1859 | | Use concrete types when possible for improved performance | +CA2021 | | Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types | diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs new file mode 100644 index 0000000000..e4390ffb88 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs @@ -0,0 +1,723 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< + Microsoft.NetCore.Analyzers.Runtime.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; +using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< + Microsoft.NetCore.Analyzers.Runtime.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Runtime.UnitTests +{ + public class DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests + { + private readonly DiagnosticDescriptor castRule = DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.CastRule; + private readonly DiagnosticDescriptor ofTypeRule = DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.OfTypeRule; + + [Fact] + public async Task OnlyWellKnownIEnumerable() + { + await VerifyCS.VerifyAnalyzerAsync(@" +namespace System.Linq +{ + interface IEnumerable {} + // this 'IEnumerable' isn't 'well known', so the analyzer won't fire + interface IEnumerable : IEnumerable {} + + static class Enumerable + { + public static IEnumerable OfType(this IEnumerable ienum) => null; + } + + class C + { + void M() + { + _ = Enumerable.OfType(default(IEnumerable)); + _ = default(IEnumerable).OfType(); + } + } +} +"); + } + + [Fact()] + public async Task UnrelatedMethodsDontTrigger() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + static class Enumerable + { + // missing 'this' + public static IEnumerable Cast(IEnumerable ienum) => null; + // wrong parameter type + public static IEnumerable Cast(this IEnumerable ienum) => null; + // too many parameters + public static IEnumerable Cast(this IEnumerable ienum, object distraction) => null; + // too many type parameters + public static IEnumerable Cast(this IEnumerable ienum) => null; + } + + class C + { + void M() + { + IEnumerable e = default; + _ = Enumerable.Cast(e); + _ = e.Cast(); + _ = e.Cast(null); + _ = e.Cast(); + } + } +} +"); + } + + [Fact] + public async Task NonGenericCasesCSharp() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.Linq; +class Fruit {} +class Apple : Fruit {} +class Shoe {} + +interface ICar {} + +interface IPlant {} +interface ITree : IPlant {} +interface IGrass : IPlant {} + +class Plant : IPlant {} +class Tree : ITree {} +sealed class Grass : IGrass {} + +class C +{ + public void M() + { + _ = (new int[0]).OfType(); + _ = {|#10:(new int[0]).OfType()|}; + _ = (new object[0]).OfType(); + + // we don't look through extra casts + _ = (new System.Uri[0] as object[]).OfType(); + _ = ((object[])new System.Uri[0]).OfType(); + + // expression syntax + _ = from string s in new object[0] + select s; + _ = {|#11:from int i in new string[0]|} + select i; + _ = {|#12:Enumerable.Cast(new int[0])|}; + + // interfaces + _ = (new ICar[0]).Cast(); + _ = (new ICar[0]).Cast(); + _ = (new IPlant[0]).Cast(); + _ = (new IPlant[0]).Cast(); + + // classes + _ = (new Fruit[0]).Cast(); // identity + _ = (new Fruit[0]).Cast(); // upcast + _ = {|#40:(new Fruit[0]).Cast()|}; // error + _ = (new Apple[0]).Cast(); // downcast + _ = (new Apple[0]).Cast(); // identity + _ = {|#41:(new Apple[0]).Cast()|}; // error + _ = {|#42:(new Shoe[0]).Cast()|}; // error + _ = {|#43:(new Shoe[0]).Cast()|}; // error + _ = {|#44:(new Shoe[0]).Cast()|}; // error + + // interface to class + _ = (new ICar[0]).Cast(); // subclass of Plant could implement ICar + _ = (new ICar[0]).Cast(); // subclass of Tree could implement ICar + _ = {|#50:(new ICar[0]).Cast()|}; // subclass of Grass could not implement ICar, as Grass is sealed + _ = (new ICar[0]).Cast(); // subclass of Shoe could implement ICar + + _ = (new IPlant[0]).Cast(); + _ = (new IPlant[0]).Cast(); + _ = (new IPlant[0]).Cast(); + _ = (new IPlant[0]).Cast(); + + _ = (new ITree[0]).Cast(); + _ = (new ITree[0]).Cast(); + _ = {|#51:(new ITree[0]).Cast()|}; // subclass of Grass could not implement ICar, as Grass is sealed + _ = (new ITree[0]).Cast(); + + _ = (new IGrass[0]).Cast(); + _ = (new IGrass[0]).Cast(); + _ = (new IGrass[0]).Cast(); + _ = (new IGrass[0]).Cast(); + + // class to interface + _ = (new Plant[0]).Cast(); + _ = (new Tree[0]).Cast(); + _ = {|#52:(new Grass[0]).Cast()|}; // grass doesn't implement ICar, and is sealed so a subclass couldn't either + _ = (new Shoe[0]).Cast(); + + _ = (new Plant[0]).Cast(); + _ = (new Tree[0]).Cast(); + _ = (new Grass[0]).Cast(); + _ = (new Shoe[0]).Cast(); + + _ = (new Plant[0]).Cast(); + _ = (new Tree[0]).Cast(); + _ = {|#53:(new Grass[0]).Cast()|}; + _ = (new Shoe[0]).Cast(); + + _ = (new Plant[0]).Cast(); + _ = (new Tree[0]).Cast(); + _ = (new Grass[0]).Cast(); + _ = (new Shoe[0]).Cast(); + } +} +", + +VerifyCS.Diagnostic(ofTypeRule).WithLocation(10).WithArguments("int", "string"), +VerifyCS.Diagnostic(castRule).WithLocation(11).WithArguments("string", "int"), +VerifyCS.Diagnostic(castRule).WithLocation(12).WithArguments("int", "string"), + +VerifyCS.Diagnostic(castRule).WithLocation(40).WithArguments("Fruit", "Shoe"), +VerifyCS.Diagnostic(castRule).WithLocation(41).WithArguments("Apple", "Shoe"), +VerifyCS.Diagnostic(castRule).WithLocation(42).WithArguments("Shoe", "Fruit"), +VerifyCS.Diagnostic(castRule).WithLocation(43).WithArguments("Shoe", "Apple"), + +VerifyCS.Diagnostic(castRule).WithLocation(50).WithArguments("ICar", "Grass"), +VerifyCS.Diagnostic(castRule).WithLocation(51).WithArguments("ITree", "Grass"), +VerifyCS.Diagnostic(castRule).WithLocation(52).WithArguments("Grass", "ICar"), +VerifyCS.Diagnostic(castRule).WithLocation(53).WithArguments("Grass", "ITree") +); + } + + [Fact] + public async Task ArrayCSharp() + { + Assert.Throws(() + => (new int[][] { new int[] { 1 } }).Cast().ToArray()); + Assert.Throws(() + => (new[] { 1 }).Cast().ToArray()); + + Assert.Throws(() + => (new object[][] { Array.Empty() }).Cast().ToArray()); + + Assert.Throws(() + => (new ValueType[][] { Array.Empty() }).Cast().ToArray()); + + Assert.Throws(() + => (new object[][] { Array.Empty() }).Cast().ToArray()); + + Assert.Throws(() + => (new ValueType[][] { Array.Empty() }).Cast().ToArray()); + + Assert.Throws(() + => (new int[][] { Array.Empty() }).Cast().ToArray()); + + await VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.Linq; + +class C +{ + void M() + { + Enumerable.OfType(new int[0][]); + Enumerable.OfType(new string[0][]); + Enumerable.OfType(new object[0][]); + + // these should all be errors, but not all implemented + Enumerable.OfType(new object[0][]); + Enumerable.OfType(new object[0][]); + + {|#12:Enumerable.OfType(new int[0][])|}; + {|#13:Enumerable.OfType(new int[0][])|}; + + // multidimensional arrays don't implement IEnumberable + + // IEnumerable != string[,] + {|#20:Enumerable.OfType(new string[0,0])|}; + + // these will throw + {|#21:Enumerable.OfType(new int[0,0])|}; + {|#22:Enumerable.OfType(new int[0,0])|}; + + // arrays of multidimensional arrays are checked, including rank + {|#30:Enumerable.OfType(new string[0][,])|}; + {|#31:Enumerable.OfType(new string[0][])|}; + {|#32:Enumerable.OfType(new int[0][,])|}; + {|#33:Enumerable.OfType(new int[0][])|}; + + // all arrays can be cast to and from System.Array + Enumerable.OfType(Enumerable.Empty()); + + Enumerable.OfType(Enumerable.Empty()); + Enumerable.OfType(Enumerable.Empty()); + Enumerable.OfType(Enumerable.Empty()); + Enumerable.OfType(Enumerable.Empty()); + + Enumerable.OfType(Enumerable.Empty()); + Enumerable.OfType(Enumerable.Empty()); + + // but not non-arrays + {|#41:Enumerable.OfType(Array.Empty())|}; + Enumerable.OfType(Array.Empty()); + {|#42:Enumerable.OfType(Array.Empty())|}; + {|#43:Enumerable.OfType(Array.Empty())|}; + {|#44:Enumerable.OfType(Array.Empty())|}; + + {|#51:Enumerable.OfType(Array.Empty())|}; + Enumerable.OfType(Array.Empty()); + {|#52:Enumerable.OfType(Array.Empty())|}; + {|#53:Enumerable.OfType(Array.Empty())|}; + {|#54:Enumerable.OfType(Array.Empty())|}; + + // this might work + Enumerable.OfType(Enumerable.Empty()); + // this is not allowed, but not implemented yet + Enumerable.OfType(Enumerable.Empty()); + } +}", + // VerifyCS.Diagnostic(ofTypeRule).WithLocation(10).WithArguments("int[]", "object[]"), + // VerifyCS.Diagnostic(ofTypeRule).WithLocation(11).WithArguments("string[]", "object[]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(12).WithArguments("int[]", "string[]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(13).WithArguments("int[]", "string"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(20).WithArguments("string", "string[*,*]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(21).WithArguments("int", "string[]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(22).WithArguments("int", "string[*,*]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(30).WithArguments("string[*,*]", "string[]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(31).WithArguments("string[]", "string[*,*]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(32).WithArguments("int[*,*]", "string[]"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(33).WithArguments("int[]", "string[*,*]"), + + VerifyCS.Diagnostic(ofTypeRule).WithLocation(41).WithArguments("int", "System.Array"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(42).WithArguments("string", "System.Array"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(43).WithArguments("System.ValueType", "System.Array"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(44).WithArguments("System.Enum", "System.Array"), + + VerifyCS.Diagnostic(ofTypeRule).WithLocation(51).WithArguments("System.Array", "int"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(52).WithArguments("System.Array", "string"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(53).WithArguments("System.Array", "System.ValueType"), + VerifyCS.Diagnostic(ofTypeRule).WithLocation(54).WithArguments("System.Array", "System.Enum") + +// VerifyCS.Diagnostic(ofTypeRule).WithLocation(60).WithArguments("ValueType[]", "int[]") +); + } + + [Fact] + public async Task EnumCasesCSharp() + { + Assert.Throws(() => new int[] { 1 }.Cast().ToArray()); + + // this is ok! + _ = new StringComparison[] { StringComparison.OrdinalIgnoreCase }.Cast().ToArray(); + _ = new StringComparison[] { StringComparison.OrdinalIgnoreCase }.Cast().ToArray(); + _ = new ValueType[] { StringComparison.OrdinalIgnoreCase }.Cast().ToArray(); + _ = new Enum[] { StringComparison.OrdinalIgnoreCase }.Cast().ToArray(); + _ = new ValueType[] { StringComparison.OrdinalIgnoreCase }.Cast().ToArray(); + _ = new Enum[] { StringComparison.OrdinalIgnoreCase }.Cast().ToArray(); + + await VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.Linq; + +enum ByteEnum : byte {} +enum IntEnum {} +enum IntEnum2 {} +enum UIntEnum : uint {} +enum LongEnum : long {} + +class C +{ + void M() + { + // object is everything + _ = (new object[0]).Cast(); + _ = (new IntEnum[0]).Cast(); + + // base class + _ = (new Enum[0]).Cast(); + _ = (new IntEnum[0]).Cast(); + _ = {|#10:(new int[0]).Cast()|}; + + // value type + _ = Array.Empty().Cast(); + _ = (new IntEnum[0]).Cast(); + _ = (new ValueType[0]).Cast(); + _ = (new Enum[0]).Cast(); + + // Enums with the same underlying type are OK + _ = (new IntEnum[0]).Cast(); + _ = (new IntEnum2[0]).Cast(); + + // to and from the underlying type are ok + _ = (new ByteEnum[0]).Cast(); + _ = (new IntEnum[0]).Cast(); + _ = (new UIntEnum[0]).Cast(); + _ = (new LongEnum[0]).Cast(); + + _ = Enumerable.Empty().Cast(); + _ = Enumerable.Empty().Cast(); + _ = Enumerable.Empty().Cast(); + _ = Enumerable.Empty().Cast(); + + // enums with different underlying types are not + _ = {|#20:(new IntEnum[0]).Cast()|}; + _ = {|#21:(new IntEnum[0]).Cast()|}; + + _ = {|#22:(new int[0]).Cast()|}; + _ = {|#23:(new int[0]).Cast()|}; + + _ = {|#24:(new IntEnum[0]).Cast()|}; + _ = {|#25:(new int[0]).Cast()|}; + + _ = {|#26:(new ByteEnum[0]).Cast()|}; + _ = {|#27:(new UIntEnum[0]).Cast()|}; + + _ = {|#28:(new ByteEnum[0]).Cast()|}; + _ = {|#29:(new UIntEnum[0]).Cast()|}; + + _ = {|#30:(new LongEnum[0]).Cast()|}; + _ = {|#31:(new LongEnum[0]).Cast()|}; + } +}", + VerifyCS.Diagnostic(castRule).WithLocation(10).WithArguments("int", "System.Enum"), + VerifyCS.Diagnostic(castRule).WithLocation(20).WithArguments("IntEnum", "ByteEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(21).WithArguments("IntEnum", "UIntEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(22).WithArguments("int", "ByteEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(23).WithArguments("int", "UIntEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(24).WithArguments("IntEnum", "LongEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(25).WithArguments("int", "LongEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(26).WithArguments("ByteEnum", "IntEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(27).WithArguments("UIntEnum", "IntEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(28).WithArguments("ByteEnum", "int"), + VerifyCS.Diagnostic(castRule).WithLocation(29).WithArguments("UIntEnum", "int"), + VerifyCS.Diagnostic(castRule).WithLocation(30).WithArguments("LongEnum", "IntEnum"), + VerifyCS.Diagnostic(castRule).WithLocation(31).WithArguments("LongEnum", "int") +); + } + + [Fact] + public async Task NullableValueTypeCasesCSharp() + { + _ = new ValueType[] { StringComparison.OrdinalIgnoreCase, null }.Cast().ToArray(); + + await VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.Linq; + +enum ByteEnum : byte {} +enum IntEnum {} +enum IntEnum2 {} +enum UIntEnum : uint {} +enum LongEnum : long {} + +class C +{ + void M() + { + // object is everything + _ = (new object[0]).Cast(); + _ = (new IntEnum?[0]).Cast(); + + // base class + _ = (new Enum[0]).Cast(); + _ = (new IntEnum?[0]).Cast(); + _ = {|#10:(new int?[0]).Cast()|}; + _ = {|#11:(new Enum[0]).Cast()|}; + + // value type + _ = (new Enum[0]).Cast(); + _ = Array.Empty().Cast(); + _ = (new IntEnum?[0]).Cast(); + _ = (new ValueType[0]).Cast(); + + // Enums with the same underlying type are OK + _ = (new IntEnum?[0]).Cast(); + _ = (new IntEnum2?[0]).Cast(); + + // to and from the underlying type are ok + _ = (new ByteEnum?[0]).Cast(); + _ = (new IntEnum?[0]).Cast(); + _ = (new UIntEnum?[0]).Cast(); + _ = (new LongEnum?[0]).Cast(); + + _ = Enumerable.Empty().Cast(); + _ = Enumerable.Empty().Cast(); + _ = Enumerable.Empty().Cast(); + _ = Enumerable.Empty().Cast(); + + // enums with different underlying types are not + _ = {|#20:(new IntEnum?[0]).Cast()|}; + _ = {|#21:(new IntEnum?[0]).Cast()|}; + + _ = {|#22:(new int?[0]).Cast()|}; + _ = {|#23:(new int?[0]).Cast()|}; + + _ = {|#24:(new IntEnum?[0]).Cast()|}; + _ = {|#25:(new int?[0]).Cast()|}; + + _ = {|#26:(new ByteEnum?[0]).Cast()|}; + _ = {|#27:(new UIntEnum?[0]).Cast()|}; + + _ = {|#28:(new ByteEnum?[0]).Cast()|}; + _ = {|#29:(new UIntEnum?[0]).Cast()|}; + + _ = {|#30:(new LongEnum?[0]).Cast()|}; + _ = {|#31:(new LongEnum?[0]).Cast()|}; + } +}", + VerifyCS.Diagnostic(castRule).WithLocation(10).WithArguments("int?", "System.Enum"), + VerifyCS.Diagnostic(castRule).WithLocation(11).WithArguments("System.Enum", "int?"), + + VerifyCS.Diagnostic(castRule).WithLocation(20).WithArguments("IntEnum?", "ByteEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(21).WithArguments("IntEnum?", "UIntEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(22).WithArguments("int?", "ByteEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(23).WithArguments("int?", "UIntEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(24).WithArguments("IntEnum?", "LongEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(25).WithArguments("int?", "LongEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(26).WithArguments("ByteEnum?", "IntEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(27).WithArguments("UIntEnum?", "IntEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(28).WithArguments("ByteEnum?", "int?"), + VerifyCS.Diagnostic(castRule).WithLocation(29).WithArguments("UIntEnum?", "int?"), + VerifyCS.Diagnostic(castRule).WithLocation(30).WithArguments("LongEnum?", "IntEnum?"), + VerifyCS.Diagnostic(castRule).WithLocation(31).WithArguments("LongEnum?", "int?") +); + } + + [Fact] + public async Task GenericCastsCSharp() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.Linq; + +struct Struct : IInterface {} +interface IInterface {} +interface IInterface2 {} + +sealed class S : IInterface {} +sealed class Z : IInterface, IInterface2 {} + +class C : IInterface +{ + void M() + { + (new T[0]).Cast(); // T could be anything + (new int[0]).Cast(); // T could be anything + } + + void MClass() where TClass : class + { + (new TClass[0]).Cast(); // T could be object + (new int[0]).Cast(); // T could be object + } + + void MclassC() where TClassC : C + { + (new TClassC[0]).Cast(); + (new object[0]).Cast(); + + (new TClassC[0]).Cast(); + (new TClassC[0]).Cast(); + + {|#10:(new TClassC[0]).Cast()|}; // C is not string + {|#11:(new string[0]).Cast()|}; // string is not C + + (new C[0]).Cast(); + (new IInterface[0]).Cast(); + + {|#12:(new TClassC[0]).Cast()|}; // error, subclass of C can't be int + {|#13:(new int[0]).Cast()|}; // error, int can't be subclass of C + {|#14:(new TClassC[0]).Cast()|}; // error, subclass of C can't be int + {|#15:(new string[0]).Cast()|}; // error, int can't be subclass of C + } + + void MInterface() where TInterface : IInterface + { + (new TInterface[0]).Cast(); + (new IInterface[0]).Cast(); + + (new TInterface[0]).Cast(); + (new object[0]).Cast(); + + {|#20:(new TInterface[0]).Cast()|}; + {|#21:(new int[0]).Cast()|}; + + {|#22:(new TInterface[0]).Cast()|}; + {|#23:(new string[0]).Cast()|}; + } + + void MInterface2() where TInterface : IInterface, IInterface2 + { + (new TInterface[0]).Cast(); + (new IInterface[0]).Cast(); + + (new TInterface[0]).Cast(); + (new IInterface2[0]).Cast(); + + // does implement both interfaces + (new Z[0]).Cast(); + (new TInterface[0]).Cast(); + + // doesn't implement IInterface2, but a subclass could + (new C[0]).Cast(); + (new TInterface[0]).Cast(); + + // sealed class doesn't implement IInterface2 + {|#30:(new S[0]).Cast()|}; + {|#31:(new TInterface[0]).Cast()|}; + + // struct class doesn't implement IInterface2 + {|#32:(new Struct[0]).Cast()|}; + {|#33:(new TInterface[0]).Cast()|}; + + // ok + (new TInterface[0]).Cast(); + (new object[0]).Cast(); + + {|#34:(new TInterface[0]).Cast()|}; + {|#35:(new int[0]).Cast()|}; + + {|#36:(new TInterface[0]).Cast()|}; + {|#37:(new string[0]).Cast()|}; + } + + void MStructInterface() where TStructInterface : struct, IInterface + { + {|#40:(new TStructInterface[0]).Cast()|}; // error, int doesn't implement I + {|#41:(new int[0]).Cast()|}; // error, I can't be cast to int + } + + void Mstruct() where TStruct : struct + { + (new TStruct[0]).Cast(); // int is a struct + (new TStruct[0]).Cast(); // can always cast to object + {|#50:(new TStruct[0]).Cast()|}; // string is not is a struct + + (new int[0]).Cast(); // int is a struct + (new object[0]).Cast(); // can always cast to object + {|#51:(new string[0]).Cast()|}; // string is not is a struct + } +}", + VerifyCS.Diagnostic(castRule).WithLocation(10).WithArguments("TClassC", "string"), + VerifyCS.Diagnostic(castRule).WithLocation(11).WithArguments("string", "TClassC"), + + VerifyCS.Diagnostic(castRule).WithLocation(12).WithArguments("TClassC", "int"), + VerifyCS.Diagnostic(castRule).WithLocation(13).WithArguments("int", "TClassC"), + VerifyCS.Diagnostic(castRule).WithLocation(14).WithArguments("TClassC", "string"), + VerifyCS.Diagnostic(castRule).WithLocation(15).WithArguments("string", "TClassC"), + + VerifyCS.Diagnostic(castRule).WithLocation(20).WithArguments("TInterface", "int"), + VerifyCS.Diagnostic(castRule).WithLocation(21).WithArguments("int", "TInterface"), + + VerifyCS.Diagnostic(castRule).WithLocation(22).WithArguments("TInterface", "string"), + VerifyCS.Diagnostic(castRule).WithLocation(23).WithArguments("string", "TInterface"), + + VerifyCS.Diagnostic(castRule).WithLocation(30).WithArguments("S", "TInterface"), + VerifyCS.Diagnostic(castRule).WithLocation(31).WithArguments("TInterface", "S"), + VerifyCS.Diagnostic(castRule).WithLocation(32).WithArguments("Struct", "TInterface"), + VerifyCS.Diagnostic(castRule).WithLocation(33).WithArguments("TInterface", "Struct"), + + VerifyCS.Diagnostic(castRule).WithLocation(34).WithArguments("TInterface", "int"), + VerifyCS.Diagnostic(castRule).WithLocation(35).WithArguments("int", "TInterface"), + VerifyCS.Diagnostic(castRule).WithLocation(36).WithArguments("TInterface", "string"), + VerifyCS.Diagnostic(castRule).WithLocation(37).WithArguments("string", "TInterface"), + + VerifyCS.Diagnostic(castRule).WithLocation(40).WithArguments("TStructInterface", "int"), + VerifyCS.Diagnostic(castRule).WithLocation(41).WithArguments("int", "TStructInterface"), + + VerifyCS.Diagnostic(castRule).WithLocation(50).WithArguments("TStruct", "string"), + VerifyCS.Diagnostic(castRule).WithLocation(51).WithArguments("string", "TStruct") +); + } + + [Fact] + public async Task NonGenericCasesVB() + { + var castRule = DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.CastRule; + + await VerifyVB.VerifyAnalyzerAsync(@" +Imports System.Linq + +Interface IApple +End Interface + +Public Class Fruit +End Class + +Public Class Orange + Inherits Fruit +End Class + +Class Apple + Inherits Fruit + Implements IApple +End Class + +NotInheritable Class Salad +End Class + +Module M + Sub S + Dim a1 = (New Integer(){}).Cast(Of Object) + Dim a2 = (New Object(){}).Cast(Of String) + Dim a3 = (New Object(){}).Cast(Of Integer) + Dim a4 = {|#11:(New Integer(){}).Cast(Of String)|} + Dim a5 = {|#12:(New String(){}).Cast(Of Integer)|} + + Dim b1 = (New Object(){}).Cast(Of Fruit) + Dim b2 = (New Object(){}).Cast(Of Orange) + Dim b3 = (New Object(){}).Cast(Of IApple) + Dim b4 = (New Object(){}).Cast(Of Apple) + Dim b5 = (New Object(){}).Cast(Of Salad) + + Dim c1 = (New Fruit(){}).Cast(Of Fruit) + Dim c2 = (New Fruit(){}).Cast(Of Orange) + Dim c3 = (New Fruit(){}).Cast(Of IApple) + Dim c4 = (New Fruit(){}).Cast(Of Apple) + Dim c5 = {|#15:(New Fruit(){}).Cast(Of Salad)|} + + Dim d1 = (New Orange(){}).Cast(Of Fruit) + Dim d2 = (New Orange(){}).Cast(Of Orange) + Dim d3 = (New Orange(){}).Cast(Of IApple) ' subclass of Orange could implement IApple + Dim d4 = {|#21:(New Orange(){}).Cast(Of Apple)|} + Dim d5 = {|#22:(New Orange(){}).Cast(Of Salad)|} + + Dim e1 = (New IApple(){}).Cast(Of Fruit) + Dim e2 = (New IApple(){}).Cast(Of Orange) ' subclass of Orange could implement IApple + Dim e3 = (New IApple(){}).Cast(Of IApple) + Dim e4 = (New IApple(){}).Cast(Of Apple) + Dim e5 = {|#30:(New IApple(){}).Cast(Of Salad)|} + + Dim f1 = (New Apple(){}).Cast(Of Fruit) + Dim f2 = {|#40:(New Apple(){}).Cast(Of Orange)|} + Dim f3 = (New Apple(){}).Cast(Of IApple) + Dim f4 = (New Apple(){}).Cast(Of Apple) + Dim f5 = {|#41:(New Apple(){}).Cast(Of Salad)|} + End Sub +End Module +", + VerifyVB.Diagnostic(castRule).WithLocation(11).WithArguments("Integer", "String"), + VerifyVB.Diagnostic(castRule).WithLocation(12).WithArguments("String", "Integer"), + + VerifyVB.Diagnostic(castRule).WithLocation(15).WithArguments("Fruit", "Salad"), + + VerifyVB.Diagnostic(castRule).WithLocation(21).WithArguments("Orange", "Apple"), + VerifyVB.Diagnostic(castRule).WithLocation(22).WithArguments("Orange", "Salad"), + + VerifyVB.Diagnostic(castRule).WithLocation(30).WithArguments("IApple", "Salad"), + + VerifyVB.Diagnostic(castRule).WithLocation(40).WithArguments("Apple", "Orange"), + VerifyVB.Diagnostic(castRule).WithLocation(41).WithArguments("Apple", "Salad") + ); + } + } +} From 0cbb96db24c9ad71d2d1140ed63d5463aec08659 Mon Sep 17 00:00:00 2001 From: James May Date: Mon, 9 Jan 2023 21:58:22 +1100 Subject: [PATCH 2/7] apply suggestions --- ...stOrOfTypeWithIncompatibleTypesAnalyzer.cs | 25 +++++++++++-------- ...fTypeWithIncompatibleTypesAnalyzerTests.cs | 1 - .../DiagnosticCategoryAndIdRanges.txt | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs index 4272e672a4..84110efd47 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer.cs @@ -10,6 +10,8 @@ namespace Microsoft.NetCore.Analyzers.Runtime { + using static MicrosoftNetCoreAnalyzersResources; + /// /// CA2021: Do not call Enumerable.Cast or Enumerable.OfType with incompatible types. /// @@ -18,11 +20,11 @@ public sealed class DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer { internal const string RuleId = "CA2021"; - private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableTitle = CreateLocalizableResourceString(nameof(DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesTitle)); + private static readonly LocalizableString s_localizableDescription = CreateLocalizableResourceString(nameof(DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesDescription)); - private static readonly LocalizableString s_localizableCastMessage = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesMessageCast), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableOfTypeMessage = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesMessageOfType), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableCastMessage = CreateLocalizableResourceString(nameof(DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesMessageCast)); + private static readonly LocalizableString s_localizableOfTypeMessage = CreateLocalizableResourceString(nameof(DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesMessageOfType)); internal static DiagnosticDescriptor CastRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, @@ -47,8 +49,8 @@ public sealed class DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer (nameof(Enumerable.OfType), OfTypeRule) ); - public override ImmutableArray SupportedDiagnostics - => ImmutableArray.Create(OfTypeRule, CastRule); + public override ImmutableArray SupportedDiagnostics { get; } + = ImmutableArray.Create(OfTypeRule, CastRule); public override void Initialize(AnalysisContext context) { @@ -195,6 +197,7 @@ static ITypeSymbol UnwrapNullableValueType(ITypeSymbol typeSymbol) { return nullableTypeArgument; } + return typeSymbol; } @@ -231,6 +234,7 @@ static bool IsUnconstrainedTypeParameter(ITypeParameterSymbol typeParameterSymbo { return true; } + return false; case (_, TypeKind.TypeParameter): var castToTypeParam = (ITypeParameterSymbol)castTo.OriginalDefinition; @@ -249,6 +253,7 @@ static bool IsUnconstrainedTypeParameter(ITypeParameterSymbol typeParameterSymbo { return true; } + return false; case (TypeKind.Class, TypeKind.Class): @@ -261,11 +266,11 @@ static bool IsUnconstrainedTypeParameter(ITypeParameterSymbol typeParameterSymbo return castFrom.IsSealed && !castFrom.AllInterfaces.Contains(castTo); case (TypeKind.Class, TypeKind.Enum): - return castFrom.OriginalDefinition.SpecialType != SpecialType.System_Enum - && castFrom.OriginalDefinition.SpecialType != SpecialType.System_ValueType; + return castFrom.OriginalDefinition.SpecialType is not SpecialType.System_Enum + and not SpecialType.System_ValueType; case (TypeKind.Enum, TypeKind.Class): - return castTo.OriginalDefinition.SpecialType != SpecialType.System_Enum - && castTo.OriginalDefinition.SpecialType != SpecialType.System_ValueType; + return castTo.OriginalDefinition.SpecialType is not SpecialType.System_Enum + and not SpecialType.System_ValueType; case (TypeKind.Struct, TypeKind.Enum) when castTo.OriginalDefinition is INamedTypeSymbol toEnum: diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs index e4390ffb88..6d2faf82d4 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Testing; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< Microsoft.NetCore.Analyzers.Runtime.DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzer, diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt index ed679ecdfe..8641989f9e 100644 --- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt +++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt @@ -18,7 +18,7 @@ Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2260 Naming: CA1700-CA1727 Interoperability: CA1400-CA1422 Maintainability: CA1500-CA1513 -Reliability: CA9998-CA9999, CA2000-CA2020 +Reliability: CA9998-CA9999, CA2000-CA2021 Documentation: CA1200-CA1200 # Microsoft CodeAnalysis API rules From 2d4500f2fa278bc54288ed07e2e3f1ae8bc426ac Mon Sep 17 00:00:00 2001 From: James May Date: Mon, 9 Jan 2023 22:34:11 +1100 Subject: [PATCH 3/7] update xlf --- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 15 ----------- .../MicrosoftNetCoreAnalyzersResources.de.xlf | 26 +++++++++++++++++++ .../MicrosoftNetCoreAnalyzersResources.es.xlf | 26 +++++++++++++++++++ .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 26 +++++++++++++++++++ .../MicrosoftNetCoreAnalyzersResources.it.xlf | 15 ----------- .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 15 ----------- .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 15 ----------- .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 15 ----------- ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 15 ----------- .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 15 ----------- .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 15 ----------- ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 15 ----------- ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 15 ----------- 13 files changed, 78 insertions(+), 150 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index 3a9b3870e7..6ab314a7ff 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - Když konstruktor zavolá virtuální metodu, konstruktor dané instance, která metodu vyvolala, se nemusí spustit. - - - - Do not call overridable methods in constructors - Nevolejte přepsatelné metody v konstruktorech - - - - Do not call overridable methods in constructors - Nevolejte přepsatelné metody v konstruktorech - - Do not call {0} on an {1} value Nevolejte {0} pro hodnotu {1}. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index 3f43854185..676ff140a0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -552,6 +552,32 @@ Wenn eine Instanz der Klasse "{0}" deserialisiert wird, kann die Methode "{1}" die gefährliche Methode "{2}" aufrufen. Mögliche Methodenaufrufe: {3} + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + Do not call {0} on an {1} value "{0}" nicht für einen {1}-Wert aufrufen diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index ef43bf6356..14320b99da 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -552,6 +552,32 @@ Al deserializar una instancia de la clase {0}, el método {1} puede llamar al método peligroso {2}. Invocaciones de métodos posibles: {3}. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + Do not call {0} on an {1} value No llame a {0} en un valor {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index 8c6a1af19b..52d3a8d533 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -552,6 +552,32 @@ Quand vous désérialisez une instance de la classe {0}, la méthode {1} peut appeler une méthode dangereuse {2}. Les appels de méthode potentiels sont : {3}. + + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. +The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. +Widening and user defined conversions are not supported with generic types. + + + + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + Type '{0}' is incompatible with type '{1}' and cast attempts will throw InvalidCastException at runtime + + + + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + This call will always result in an empty sequence because type '{0}' is incompatible with type '{1}' + + + + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types + + Do not call {0} on an {1} value Ne pas appeler {0} sur une valeur {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index 41f5e6d670..511d26b733 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - Quando un costruttore chiama un metodo virtuale, è possibile che il costruttore per l'istanza che richiama il metodo non sia stato eseguito. - - - - Do not call overridable methods in constructors - Non chiamare metodi sottoponibili a override nei costruttori - - - - Do not call overridable methods in constructors - Non chiamare metodi sottoponibili a override nei costruttori - - Do not call {0} on an {1} value Non chiamare {0} su un valore {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index ee0ec64aa7..79de8ae9c7 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - コンストラクターが仮想メソッドを呼び出すときに、メソッドを呼び出すインスタンスのコンストラクターは実行されていない可能性があります。 - - - - Do not call overridable methods in constructors - コンストラクターのオーバーライド可能なメソッドを呼び出しません - - - - Do not call overridable methods in constructors - コンストラクターのオーバーライド可能なメソッドを呼び出しません - - Do not call {0} on an {1} value {1} 値で {0} を呼び出さないでください diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 27a435f256..4808a1f68f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - 생성자에서 가상 메서드를 호출하면 메서드를 호출하는 인스턴스에 대한 생성자가 실행되지 않을 수 있습니다. - - - - Do not call overridable methods in constructors - 생성자에서 재정의 가능한 메서드를 호출하지 마세요. - - - - Do not call overridable methods in constructors - 생성자에서 재정의 가능한 메서드를 호출하지 마세요. - - Do not call {0} on an {1} value {1} 값의 {0}을(를) 호출하지 마세요. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index fdaf3f0db9..5e67490bc2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - Gdy konstruktor wywołuje metodę wirtualną, konstruktor wystąpienia wywołującego metodę może nie zostać wykonany. - - - - Do not call overridable methods in constructors - Nie wywołuj w konstruktorach metod, które można przesłaniać - - - - Do not call overridable methods in constructors - Nie wywołuj w konstruktorach metod, które można przesłaniać - - Do not call {0} on an {1} value Nie wywołuj elementu {0} dla wartości {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index 6018910c76..d6890495f3 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - Quando um construtor chama um método virtual, o construtor para a instância que invoca o método pode não ter sido executado. - - - - Do not call overridable methods in constructors - Não chamar métodos substituíveis em construtores - - - - Do not call overridable methods in constructors - Não chamar métodos substituíveis em construtores - - Do not call {0} on an {1} value Não chamar {0} em um valor {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index 863da7fb53..0c8f219bb9 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - Когда конструктор вызывает виртуальный метод, конструктор может не выполняться для экземпляра, вызывающего этот метод. - - - - Do not call overridable methods in constructors - Не вызывайте переопределяемые методы в конструкторах - - - - Do not call overridable methods in constructors - Не вызывайте переопределяемые методы в конструкторах - - Do not call {0} on an {1} value Не вызывайте {0} для значения {1} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index 327a478a76..3ed6eac320 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - Bir oluşturucu tarafından sanal bir yöntem çağrıldığında, yöntemi tetikleyen örneğin oluşturucusu yürütülmemiş olabilir. - - - - Do not call overridable methods in constructors - Oluşturucularda geçersiz kılınabilen yöntemleri çağırmayın - - - - Do not call overridable methods in constructors - Oluşturucularda geçersiz kılınabilen yöntemleri çağırmayın - - Do not call {0} on an {1} value Bir {1} değeri üzerinde {0} çağırmayın diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index 71fc63a7bd..a427274f00 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - 构造函数调用虚方法时,可能尚未执行调用该方法的实例的构造函数。 - - - - Do not call overridable methods in constructors - 不要在构造函数中调用可重写的方法 - - - - Do not call overridable methods in constructors - 不要在构造函数中调用可重写的方法 - - Do not call {0} on an {1} value 请勿对 {1} 值调用 {0} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index f81c59ec82..edd42b2830 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -578,21 +578,6 @@ Widening and user defined conversions are not supported with generic types.Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types - - When a constructor calls a virtual method, the constructor for the instance that invokes the method may not have executed. - 當建構函式呼叫虛擬方法時,可能尚未執行叫用方法之執行個體的建構函式。 - - - - Do not call overridable methods in constructors - 請勿呼叫建構函式中的可覆寫方法 - - - - Do not call overridable methods in constructors - 請勿呼叫建構函式中的可覆寫方法 - - Do not call {0} on an {1} value 請勿對 {1} 值呼叫 {0} From 3de1ab6ca5b7a07c7d32a8f2e13d690aeed33f82 Mon Sep 17 00:00:00 2001 From: James May Date: Mon, 9 Jan 2023 22:51:33 +1100 Subject: [PATCH 4/7] fix build --- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 8701baf5de..9c2cef2ba0 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -1860,7 +1860,7 @@ Some built-in operators added in .NET 7 behave differently when overflowing than |CodeFix|False| --- -## [CA2021](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2019): Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types +## [CA2021](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021): Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types Enumerable.Cast\ and Enumerable.OfType\ require compatible types to function expectedly. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 8d1441983b..ff0f959ea7 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -3363,7 +3363,7 @@ "shortDescription": "Do not call Enumerable.Cast or Enumerable.OfType with incompatible types", "fullDescription": "Enumerable.Cast and Enumerable.OfType require compatible types to function expectedly. \u000aThe generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast will throw InvalidCastException at runtime on elements of the types specified. \u000aThe generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType will never succeed with elements of types specified, resulting in an empty sequence. \u000aWidening and user defined conversions are not supported with generic types.", "defaultLevel": "warning", - "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021", + "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021", "properties": { "category": "Reliability", "isEnabledByDefault": true, From 3d0886d6e3b0f80efb978c075022af994ac1d50e Mon Sep 17 00:00:00 2001 From: James May Date: Mon, 9 Jan 2023 22:54:14 +1100 Subject: [PATCH 5/7] fix build 2 --- src/NetAnalyzers/RulesMissingDocumentation.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index c37e954e76..82816f7747 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -10,6 +10,5 @@ CA1512 | | Use ObjectDisposedException throw helper | CA1856 | | Incorrect usage of ConstantExpected attribute | CA1857 | | A constant is expected for the parameter | -CA1858 | | Use 'StartsWith' instead of 'IndexOf' | CA1859 | | Use concrete types when possible for improved performance | -CA2021 | | Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types | +CA2021 | | Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types | From f7a404003ccd9d82b4ff472b11ccc9bedb7f256b Mon Sep 17 00:00:00 2001 From: James May Date: Mon, 16 Jan 2023 15:15:47 +1100 Subject: [PATCH 6/7] remove misleading test line --- ...llEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs index 6d2faf82d4..54a52a2617 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DoNotCallEnumerableCastOrOfTypeWithIncompatibleTypesAnalyzerTests.cs @@ -135,7 +135,6 @@ public void M() _ = {|#41:(new Apple[0]).Cast()|}; // error _ = {|#42:(new Shoe[0]).Cast()|}; // error _ = {|#43:(new Shoe[0]).Cast()|}; // error - _ = {|#44:(new Shoe[0]).Cast()|}; // error // interface to class _ = (new ICar[0]).Cast(); // subclass of Plant could implement ICar From aea7a19687199a79340523b4ddc8812070ae99fb Mon Sep 17 00:00:00 2001 From: James May Date: Mon, 16 Jan 2023 22:03:56 +1100 Subject: [PATCH 7/7] fix description typo --- .../MicrosoftNetCoreAnalyzersResources.resx | 2 +- .../xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.de.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.es.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.it.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf | 4 ++-- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +- 16 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 7383be62bc..586e290212 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1730,7 +1730,7 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index 6ab314a7ff..3c7fec79a6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index 676ff140a0..3c32e8a463 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index 14320b99da..542233b588 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index 52d3a8d533..54701481eb 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index 511d26b733..6ed67554ee 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index 79de8ae9c7..a0e3c9be01 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 4808a1f68f..703601078b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index 5e67490bc2..fa16e67807 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index d6890495f3..a04b6b1c7e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index 0c8f219bb9..f39583f65e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index 3ed6eac320..338a9b614e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index a427274f00..d3573fbdfe 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index edd42b2830..1a934c83cd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -554,11 +554,11 @@ Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. Enumerable.Cast<T> and Enumerable.OfType<T> require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast<T> will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType<T> will never succeed with elements of types specified, resulting in an empty sequence. Widening and user defined conversions are not supported with generic types. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 9c2cef2ba0..f230f3a757 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -1864,7 +1864,7 @@ Some built-in operators added in .NET 7 behave differently when overflowing than Enumerable.Cast\ and Enumerable.OfType\ require compatible types to function expectedly. -The generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast\ will throw InvalidCastException at runtime on elements of the types specified. +The generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast\ will throw InvalidCastException at runtime on elements of the types specified. The generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType\ will never succeed with elements of types specified, resulting in an empty sequence. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index ff0f959ea7..b90feb70d6 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -3361,7 +3361,7 @@ "CA2021": { "id": "CA2021", "shortDescription": "Do not call Enumerable.Cast or Enumerable.OfType with incompatible types", - "fullDescription": "Enumerable.Cast and Enumerable.OfType require compatible types to function expectedly. \u000aThe generic cast (IL 'unbox.any') used by the sequenced returned by Enumerable.Cast will throw InvalidCastException at runtime on elements of the types specified. \u000aThe generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType will never succeed with elements of types specified, resulting in an empty sequence. \u000aWidening and user defined conversions are not supported with generic types.", + "fullDescription": "Enumerable.Cast and Enumerable.OfType require compatible types to function expectedly. \u000aThe generic cast (IL 'unbox.any') used by the sequence returned by Enumerable.Cast will throw InvalidCastException at runtime on elements of the types specified. \u000aThe generic type check (C# 'is' operator/IL 'isinst') used by Enumerable.OfType will never succeed with elements of types specified, resulting in an empty sequence. \u000aWidening and user defined conversions are not supported with generic types.", "defaultLevel": "warning", "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021", "properties": {