Fix X1019: Added special-cases handling to correctly validate types convertible to IEnumerable<T[]> #199
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes xunit/xunit#3411
Added special-cases handling to MemberDataShouldReferenceValidMember.cs
TfromIEnumerable<T>and treats any array type (T[]) as assignable toobject[]. This enablesIEnumerable<string[]>to be recognized as a valid MemberData reference type.IEnumerable<T[]>by analyzing their source‑declared type syntax. As a result, classes declared such asclass NamedTypeForIEnumerableStringArray : IEnumerable<string[]>are now correctly identified as valid MemberData reference types.Alternatives explored:
compilation.ClassifyConversion(fromType, toType), I found that Roslyn often reportsIsImplicit = truefor conversions that are not actually valid at runtime. Because of this, it isn’t a reliable mechanism for determining true assignability or convertibility between types.ITypeSymbol/INamedTypeSymbol. For example, in the case ofNamedTypeForIEnumerableStringArrayclass, the implemented interface appeared asIEnumerable<T>rather thanIEnumerable<string[]>, which prevents inspection of the actual generic type argument. To address this, I leveraged the source‑declared type syntax instead, allowing me to accurately extract the generic argument and walk the declared base‑type chain.Tests updated to cover these scenarios and ensure existing diagnostics remain stable.
Notes
I’d welcome any feedback on this, as it’s my first contribution to this repository. Some of the logic I introduced could potentially be folded into
SymbolExtensions.IsAssignableFrom()to improve its handling of special‑case assignability scenarios, particularly where non‑exact matches are interesting. However, since that method is widely used across the codebase, I opted to implement the special‑case handling locally to avoid unintended regressions, especially given my limited familiarity with the repo.