खाली IAsyncEnumerable बनाएँ


25

मेरा एक इंटरफ़ेस है जो इस तरह लिखा गया है:

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;
}

कोई उपाय?

जवाबों:


28

यदि आप 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
    }
}

आपके शीघ्र उत्तर और सुझाव के लिए धन्यवाद। मैं उम्मीद कर रहा था कि ढांचे में कुछ मौजूद है।
घन 45

@ क्यूब 45: मैं आमतौर पर System.Linq.Async"फ्रेमवर्क के लगभग हिस्से" के रूप में मानता हूं । बहुत कम है सिर्फ netstandard2.1 में जब यह बात आती है IAsyncEnumerable<T>
जॉन स्कीट

@ cube45 मैं पैकेज का उपयोग नहीं करने के बारे में सावधान रहना होगा कि async प्रवाह के साथ कई क्वार्क हैं जो आपको पता चल जाएगा जब आप इसे और अधिक उपयोग करना शुरू करते हैं जब तक कि आप वास्तव में नहीं जानते कि आप जो कर रहे हैं मैं वास्तव में सोने की डली पर कर रहा हूं।
फिलिप कॉर्ड

आपके उत्तर के लिए धन्यवाद। मैंने पहले कभी IAsyncEnumerable का उपयोग नहीं किया था, और मैं केवल प्रयोग कर रहा था, कुछ "असली के लिए" नहीं कर रहा था। आप शायद सही हैं, पैकेज उपयोगी हो सकता है।
cube45

वहाँ एक समस्या है अगर यह efcore के साथ प्रयोग किया जा रहा है github.com/dotnet/efcore/issues/18124 के
Pavel Shastov

11

यदि किसी कारण से आप जॉन के जवाब में वर्णित पैकेज को स्थापित नहीं करना चाहते हैं, तो आप 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>()मामलों के लिए एक संक्षिप्त कार्यान्वयन प्रदान करता है जिनकी आपको आवश्यकता है और आप पैकेज का उपयोग नहीं करना / कर सकते हैं। आप पैकेज में इस्तेमाल कार्यान्वयन पा सकते हैं यहाँ


आपके उत्तर के लिए धन्यवाद। वास्तव में, यह भी एक विकल्प होगा। मुझे लगता है कि मैं दूसरे पैकेज को स्थापित करने के बजाय उस तरह से पसंद करूंगा। मैं इसे स्वीकार करूँगा। Nitpick: आप "एक्सटेंशन मेथड" कहते हैं जबकि यह एक स्टैटिक क्लास में सिर्फ एक स्टैटिक तरीका है।
cube45

1
@ cube45: तो क्या आप अतुल्यकालिक अनुक्रमों के साथ किसी LINQ कार्यक्षमता का उपयोग करने की योजना नहीं बना रहे हैं? क्योंकि जैसे ही आप कुछ भी करना चाहते हैं, आप सामान्य रूप से तुल्यकालिक LINQ के साथ करेंगे, आपको System.Linq.Async की आवश्यकता होगी।
जॉन स्कीट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.