yield return is C# iterator syntax for producing one element at a time. It lets a method expose an enumeration without first building an array or List containing every value. section 6.6.3
When xUnit requests MemberData, it obtains the member's IEnumerable and enumerates it through the test cases. Each yield return supplies the next parameter set as enumeration proceeds. section 6.6.3
Use yield return carefully when generating test data:
- Create a fresh test object for every yielded case; reusing one board can make xUnit treat cases as duplicates and skip them. section 6.6.3
- Prefer it when the producer does not need to materialize all values in an additional collection. section 6.6.3
- Combine async with yield return when processing an IAsyncEnumerable requires await; use await foreach to consume the incoming asynchronous sequence. section 8.2
Generating independent theory cases
public static IEnumerable<object[]> Boards\n{\n get\n {\n var board = new ArrayBoard(4);\n board[1, 0] = 1;\n board[3, 0] = 1;\n yield return new object[] { board, false };\n\n board = new ArrayBoard(4);\n board[1, 0] = 1;\n board[1, 2] = 1;\n yield return new object[] { board, false };\n }\n}\n\nEach yielded object array represents one MemberData invocation, and each board is newly allocated before being returned. section 6.6.3
Yielding asynchronous results
public async IAsyncEnumerable<Comic> Find(string searchText)\n{\n var foundComics = FindComicsByText(searchText);\n\n await foreach (var comic in foundComics)\n {\n comic.Image = await GetComicImageAsync(comic.ImgUrl);\n yield return comic;\n }\n}\n\nThe method processes each asynchronous result, enriches it, and yields it as part of an async stream. section 8.2
Listing 6.18 Theory test using MemberData
[Theory]
[MemberData(nameof(Boards))] #1
public void CheckRules(IBoard board, bool isValid) #2
{
var solver = new Solver(board);
Assert.Equal(isValid, solver.IsValid());
}
public static IEnumerable<object[]> Boards #3
{
get
{
IBoard board = new ArrayBoard(4); #4
board[1, 0] = 1;
board[3, 0] = 1;
yield return new object[] { board, false }; #5
board = new ArrayBoard(4); #6
board[1, 0] = 1;
board[1, 2] = 1;
yield return new object[] { board, false };
board = new ArrayBoard(4); #7
board[1, 2] = 1;
board[0, 3] = 1;
yield return new object[] { board, false };
board = new ArrayBoard(4); #8
board[1, 1] = 1;
board[2, 3] = 1;
yield return new object[] { board, true };
}
}
Inspect the complete MemberData example, including the theory declaration and successive yielded Sudoku boards. section 6.6.3
Listing 8.6 Operating on an IAsyncEnumerable
private IAsyncEnumerable<Comic> FindComicsByText(
string searchText) { } #1
private async Task<Image> GetComicImageAsync(
string imgUrl) { } #1
public async IAsyncEnumerable<Comic> Find( #2
string searchText)
{
var foundComics = FindComicsByText(searchText); #3
await foreach (var comic in foundComics) #4
{
comic.Image = await GetComicImageAsync(comic.ImgUrl); #5
yield return comic; #6
}
}
Inspect the async-stream example that consumes an IAsyncEnumerable, awaits image loading, and yields enriched comics. section 8.2









