我有一个界面是这样写的:
public interface IItemRetriever
{
public IAsyncEnumerable<string> GetItemsAsync();
}我想编写一个不返回任何项的空实现,如下所示:
public class EmptyItemRetriever : IItemRetriever
{
public IAsyncEnumerable<string> GetItemsAsync()
{
// What do I put here if nothing is to be done?
}
}如果它是一个普通的IEnumerable,我会return Enumerable.Empty<string>();,但是我没有找到任何AsyncEnumerable.Empty<string>()。
解决办法
我发现这个很管用,但很奇怪:
public async IAsyncEnumerable<string> GetItemsAsync()
{
await Task.CompletedTask;
yield break;
}有什么想法吗?
发布于 2019-12-22 10:45:56
如果您安装了System.Linq.Async包,您应该能够使用AsyncEnumable.Empty<string>()。下面是一个完整的例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
IAsyncEnumerable<string> empty = AsyncEnumerable.Empty<string>();
var count = await empty.CountAsync();
Console.WriteLine(count); // Prints 0
}
}发布于 2019-12-22 11:33:01
如果出于任何原因,您不希望安装琼恩的答案中提到的包,您可以创建如下方法AsyncEnumerable.Empty<T>():
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public static class AsyncEnumerable
{
public static IAsyncEnumerator<T> Empty<T>() => EmptyAsyncEnumerator<T>.Instance;
class EmptyAsyncEnumerator<T> : IAsyncEnumerator<T>
{
public static readonly EmptyAsyncEnumerator<T> Instance =
new EmptyAsyncEnumerator<T>();
public T Current => default!;
public ValueTask DisposeAsync() => default;
public ValueTask<bool> MoveNextAsync() => new ValueTask<bool>(false);
}
}注意:答案并不妨碍使用System.Linq.Async包。这个答案提供了一个AsyncEnumerable.Empty<T>()的简单实现,用于您需要它的情况,并且您不能/不想使用这个包。您可以找到包这里中使用的实现。
发布于 2021-05-14 16:05:27
我想避免安装System.Linq.Async (因为它的命名空间冲突问题),但是先前的回答实际上并没有按照最初问题中的要求实现IAsyncEnumerable<T>。这里有一个完整的解决方案,它实现了这个接口,以便很容易地以与现在的AsyncEnumerable.Empty<T>相同的方式调用Enumerable.Empty<T>。
public static class AsyncEnumerable
{
/// <summary>
/// Creates an <see cref="IAsyncEnumerable{T}"/> which yields no results, similar to <see cref="Enumerable.Empty{TResult}"/>.
/// </summary>
public static IAsyncEnumerable<T> Empty<T>() => EmptyAsyncEnumerator<T>.Instance;
private class EmptyAsyncEnumerator<T> : IAsyncEnumerator<T>, IAsyncEnumerable<T>
{
public static readonly EmptyAsyncEnumerator<T> Instance = new EmptyAsyncEnumerator<T>();
public T Current => default;
public ValueTask DisposeAsync() => default;
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return this;
}
public ValueTask<bool> MoveNextAsync() => new ValueTask<bool>(false);
}
}https://stackoverflow.com/questions/59443429
复制相似问题