Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.6.1: Ambiguous call errors for Assert.Contains<T>(T, ISet<T>) and Assert.Contains<T>(T, IReadOnlySet<T>) #2811

Closed
craigktreasure opened this issue Nov 4, 2023 · 5 comments

Comments

@craigktreasure
Copy link

craigktreasure commented Nov 4, 2023

After attempting to upgrade from 2.5.2 to 2.6.1, I received errors about ambiguous calls for Assert.Contains and Assert.DoesNotContain:

  • error CS0121: The call is ambiguous between the following methods or properties: 'Assert.DoesNotContain<T>(T, ISet<T>)' and 'Assert.DoesNotContain<T>(T, IReadOnlySet<T>)'
  • error CS0121: The call is ambiguous between the following methods or properties: 'Assert.Contains<T>(T, ISet<T>)' and 'Assert.Contains<T>(T, IReadOnlySet<T>)'

This occurs for a set type that implements both ISet<T> and IReadOnlySet<T>, like HashSet<T>.

Example that previously worked:

SetAndReadOnlySet<int> set = new()
{
    1,
    2,
};

Assert.Contains(1, set);
Assert.DoesNotContain(0, set);

You can of course workaround by casting the set to either an ISet<int> or IReadOnlySet<int>, which is what will be necessary if this breaking change was intended.

@bradwilson
Copy link
Member

Unfortunately there's not much we can do about compiler ambiguity. We have overloads for the common concrete types, but when using a third party concrete type, you'll either have to ensure variables are of a non-ambiguous type, or extend the assertion library to include your custom concrete type(s).

https://github.com/xunit/assert.xunit/blob/cb1e33ba612d4829e0848a44bde1026f5f9e3576/SetAsserts.cs#L68-L92

@craigktreasure
Copy link
Author

Unfortunately there's not much we can do about compiler ambiguity. We have overloads for the common concrete types, but when using a third party concrete type, you'll either have to ensure variables are of a non-ambiguous type, or extend the assertion library to include your custom concrete type(s).

https://github.com/xunit/assert.xunit/blob/cb1e33ba612d4829e0848a44bde1026f5f9e3576/SetAsserts.cs#L68-L92

To be clear and as noted in the OP, the HashSet<T> type, which is not third-party, will also have this issue as it implements ISet<T> and IReadOnlySet<T>.

@bradwilson
Copy link
Member

bradwilson commented Nov 9, 2023

No, HashSet<T> has a concrete overload already, as I linked to. We have tests that show it works without casting. Example:

var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "forty-two" };
Assert.Contains("FORTY-two", set);

@craigktreasure
Copy link
Author

No, HashSet<T> has a concrete overload already, as I linked to. We have tests that show it works without casting. Example:

var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "forty-two" };
Assert.Contains("FORTY-two", set);

Ah! I missed that. Thanks for the clarification.

@AndriySvyryd
Copy link

This is still an issue for SortedSet<>, and ImmutableSortedSet<>

bradwilson added a commit to xunit/assert.xunit that referenced this issue Dec 7, 2023
bradwilson added a commit that referenced this issue Dec 7, 2023
bradwilson added a commit that referenced this issue Dec 7, 2023
ViktorHofer added a commit to dotnet/arcade that referenced this issue Jan 19, 2024
…a6..141681779

141681779 Missed #nullable enable in AsyncCollectionAsserts
22c89b0ea xunit/xunit#2367: Add IAsyncEnumerable<> overloads (.NET Core 3.0+)
d5c32630a While formatting type names in Assert.Equal/NotEqual, convert generated type names to '<generated>'
d7b807179 Add platform conditionals to support .NET 6 Roslyn Analyzers
6d9024665 xunit/xunit#2850: Assert.Equal failing value-slot collections of different concrete types (also fixed for KeyValuePair keys and values)
1f66b837a xunit/xunit#2811: Add SortedSet and ImmutableSortedSet overloads for Assert.Contains/DoesNotContain
1dab747d3 Update FuncEqualityComparer to throw if GetHashCode is called, and update EqualException/NotEqualException to process it
6e0a7cd70 xunit/xunit#2828: Prefer IEquatable<> over custom collection equality
c35ef46d5 xunit/xunit#2824: Assert.Equal fails with null values in dictionary
455865ac8 xunit/xunit#2821: Assert.Equal for collections of IEquatable objects don't call custom Equals
9af2c9c12 Clarify names for range comparer
2e6d9b267 Updates for .NET 8 SDK

git-subtree-dir: src/Microsoft.DotNet.XUnitAssert/src
git-subtree-split: 141681779e7638887a2ba711ad5407c67b6efe32
ViktorHofer added a commit to dotnet/arcade that referenced this issue Mar 28, 2024
…a6..574aebac4

574aebac4 xunit/xunit#2872: Expand special handling for sets in Assert.Contains/DoesNotContain
3b8edcbf1 xunit/xunit#2880: Update XML documentation for string-based Assert.Equal
d9f8361d2 Consolidate string and span-based Assert.Equal primary implementation
9ad71163e Move span-of-char assertions to StringAsserts and update docs/param names to indicate they're treated like strings
d70b34621 xunit/xunit#2871: Inner exception stack trace is missing from Assert.Collection failure
141681779 Missed #nullable enable in AsyncCollectionAsserts
22c89b0ea xunit/xunit#2367: Add IAsyncEnumerable<> overloads (.NET Core 3.0+)
d5c32630a While formatting type names in Assert.Equal/NotEqual, convert generated type names to '<generated>'
d7b807179 Add platform conditionals to support .NET 6 Roslyn Analyzers
6d9024665 xunit/xunit#2850: Assert.Equal failing value-slot collections of different concrete types (also fixed for KeyValuePair keys and values)
1f66b837a xunit/xunit#2811: Add SortedSet and ImmutableSortedSet overloads for Assert.Contains/DoesNotContain
1dab747d3 Update FuncEqualityComparer to throw if GetHashCode is called, and update EqualException/NotEqualException to process it
6e0a7cd70 xunit/xunit#2828: Prefer IEquatable<> over custom collection equality
c35ef46d5 xunit/xunit#2824: Assert.Equal fails with null values in dictionary
455865ac8 xunit/xunit#2821: Assert.Equal for collections of IEquatable objects don't call custom Equals
9af2c9c12 Clarify names for range comparer
2e6d9b267 Updates for .NET 8 SDK

git-subtree-dir: src/Microsoft.DotNet.XUnitAssert/src
git-subtree-split: 574aebac41dbbbf9e5e98bb9c65c6c5fab9b47f5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants