2012-08-30 16 views
11

मैं वास्तव में सी # 5.0 असीमित प्रोग्रामिंग के साथ काम करने का आनंद ले रहा हूं। हालांकि, कुछ ऐसे स्थान हैं जहां टीएपी मॉडल के साथ पुराने कोड को अद्यतन करने के लिए अद्यतन करना मेरे लिए समस्याएं पैदा कर रहा है।कार्य <TResult> को सी # 5.0 में लपेटा जा सकता है जो ट्रेशल्ट में कॉन्वर्सेट है?

: मुझे यकीन है कि वास्तव में क्यों Task<TResult> TResult में covariant नहीं है नहीं कर रहा हूँ, लेकिन यह मेरे लिए समस्या उत्पन्न कर रहा है जब एक covariant इंटरफ़ेस अद्यतन करने के लिए एक तुल्यकालिक से एक एसिंक्रोनस पैटर्न के लिए ले जाने का प्रयास -

यहाँ उनमें से एक है पुराने कोड:

public interface IInitializable<out T> // ** out generic modifier ** 
{ 
    /// <summary> 
    /// Boolean to indicate if class is ready 
    /// </summary> 
    bool IsInitialized { get; } 

    /// <summary> 
    /// Calls for instance to be initialized using current parameters 
    /// Driver initialization can be done in the default constructor if desired 
    /// </summary> 
    T Initialize(); 
} 

नए कोड (संकलन नहीं होगा):

public interface IAsyncInitializable<out T> // ** out generic modifier...broken ** 
{ 
    /// <summary> 
    /// Boolean to indicate if class is ready 
    /// </summary> 
    bool IsInitialized { get; } 

    /// <summary> 
    /// Calls for instance to be initialized using current parameters 
    /// Driver initialization can be done in the default constructor if desired 
    /// </summary> 
    Task<T> InitializeAsync(); // ** breaks because Task<TResult> is invariant in TResult ** 
} 

एक उचित रास्ता मो के बिना इस के आसपास है है मेरे एपीआई बहुत भारी है? (बोनस: कार्य क्यों नहीं है?)। कोई IAwaitable इंटरफ़ेस नहीं है, लेकिन मुझे लगता है कि मैं एक बना सकता हूं और एक विस्तार विधि बना सकता हूं जो एक लिपटे, कॉन्विएन्ट, अजीब कार्य ऑब्जेक्ट में परिवर्तित हो जाता है। या मैं यह गलत कर रहा हूँ?

+2

Btw, भले ही 'Task' एक covariant इंटरफेस था, अपने कोड संकलन नहीं होगा:

में और जानकारी यहां पाया जा सकता है। सही संस्करण 'कार्य आरंभिकएसिंक(); '(उस पंक्ति पर' आउट 'संशोधक के बिना) होगा। – svick

+0

एक उत्कृष्ट बिंदु। मैं इसे वीएस में सही कर दूंगा, लेकिन एसओ संपादित करना भूल गया। –

उत्तर

12

Task<T>T में कॉन्वेंट नहीं हो सकता है, क्योंकि यह एक वर्ग है। केवल इंटरफेस और प्रतिनिधियों में सामान्य भिन्नता हो सकती है।

चाहे यह रैपिंग करने के लायक है ... मुझे लगता है कि यह इस बात पर निर्भर करता है कि आप अपनी परियोजना के भीतर कॉन्वर्सिस का कितना उपयोग करते हैं। मुझे संदेह है कि आप समय के साथ सभी लपेटने और अनजान भ्रमित हो जाएंगे, ईमानदार होने के लिए - यदि यह भी नहीं है, तो केवल इसे हटाने के लिए हिट करें, मैं ऐसा करूँगा।

+0

सलाह के लिए धन्यवाद! मैंने आपके Eduasync TaskAwaiter (T) का उपयोग करके IAwaitable (बाहर TResult) लागू किया, और देख सकता हूं कि एक अलग इंटरफ़ेस का उपयोग निश्चित रूप से पठनीयता/उपयोगिता के नुकसान के लायक नहीं है। और, महान बिंदु पुन: कक्षाएं और सामान्य भिन्नता ... मेरी गलती @Jon Skeet द्वारा इंगित करने के लिए सम्मानित :)। कोई आईटास्क (टी टी) हालांकि, एक बमर है। मैं स्टीफन क्लेरी की टिप्पणी यहां देखता हूं (http://stackoverflow.com/questions/8407227/async-generic-delegate-in-c-sharp-5-0), लेकिन WinRT इंटरऑप संगतता उपयोग करने के लिए औचित्य के रूप में थोड़ा असंतुष्ट है ठोस प्रकार। –

+1

@ डेविड क्यूसिया: जब आप प्रतीक्षाकर्ताओं की बात करते हैं तो आपको संदर्भों का प्रचार करने के बारे में स्टीफन टब के ब्लॉग पर पढ़ना चाहिए। Eduasync से थोड़ा सा ट्रिकियर दिखाता है :( –

+0

@ जोनस्केट - कोई विचार क्यों वे डेवलपर्स फ्रेमवर्क डेवलपर्स ने 'आईटास्क ' नहीं जोड़ा और केवल एक कक्षा लागू की? –

4

मेरा मानना ​​है कि आईटस्क इंटरफ़ेस पर एसिंक कीवर्ड के लिए कंपाइलर समर्थन शामिल नहीं है, माइक्रोसॉफ्ट के हिस्से पर एक प्रमुख निगरानी थी। सौभाग्य से इस सीमा के आसपास काम करना मुश्किल नहीं है।

मैंने एक कॉन्वर्सेट का प्रयास किया है ITask<out TResult> इंटरफ़ेस। इसका उपयोग बहुत सरल है।

https://github.com/jam40jeff/ITask