#2836: Support collection expression for generic TheoryData#2967
#2836: Support collection expression for generic TheoryData#2967bradwilson merged 6 commits intoxunit:mainfrom
Conversation
C# 12 compiler requires target type to support enumeration of elements of type matching Add method argument when using collection expressions.
|
@dotnet-policy-service agree |
|
This PR is for the However, I cannot back-port the change to the |
|
(The alternative way to do this, via a polyfill'd |
|
I think I've discovered an issue with this, which is: by overwriting the var TheoryData<string, int> =
[
new TheoryDataRow<string, int>("Hello", 42),
new TheoryDataRow<string, int>("World", 2112),
];It complains about not being able to convert I'm going to run a couple experiments to see if there's an easy fix. First will be to see if an implicit conversion on TheoryDataRow will make everybody happy. If not, then I'll experiment to see whether using |
…ng more compile-time type safe
|
So, here's where I landed. After playing around with implicit conversions, I decided that the most type-safe way to go about this is to leave The compiler error message when you have the wrong types does talk about the implicit conversion, but the types being there should let you know exactly what the problem is: This conversion message would be present regardless of which direction of implicit conversion is involved. |
|
Thanks! |
|
Great! Should I see if the implementation for a single argument can be added to 2.x branch? It would allow to fix IDE030* ("Use collection expression for ...") warnings. I see it's a breaking change as it changes So far I only managed to get it to work by replacing IEnumerable dataItems = ...;
...
// Current version: return dataItems.Cast<object>().Select(item => ConvertDataItem(testMethod, item));
foreach(var item in dataItems)
{
yield return ConvertDataItem(testMethod, item);
} |
|
Actually, that's an interesting edge case that's always been there for any type which multiply implements var obj = accessor();
if (obj == null)
return null;
if (obj is IEnumerable<object[]> arrayEnumerable)
return arrayEnumerable;
if (obj is not IEnumerable enumerable)
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Property {0} on {1} did not return IEnumerable", MemberName, type.FullName));
return enumerable.Cast<object>().Select(item => ConvertDataItem(testMethod, item));(Also interesting to note that the member data error messages always say "Property" regardless of the type of member that's being used.) Anyways, it's a simple change, so I just pushed it: 4850a0d |
|
This is available now in v2 |
|
Thanks! |

This pull request adds support to using C#12 collection expressions to initialize values of generic TheoryData types. This would fix #2836 without need for a future version of C#. As of xunit 2.8.1, collection expressions fail to compile due to error CS00029.
C# 12 compiler requires target type to support enumeration of elements of type matching Add method argument when using collection expressions. This pull request also adds Add overloads accepting ValueTuple argument to support multiple arguments in a single row.
Examples:
As a side note, this change may be unnecessary as collection expression requirements seem to get relaxed in a future version of C# (see dotnet/csharplang#8034).