मेरे पास जेनेरिक तरीकों के साथ बहुत मज़ाकिया मज़ा (मजेदार इरादा) है। ज्यादातर मामलों में सी # प्रकार अनुमान यह समझने के लिए पर्याप्त स्मार्ट है कि यह सामान्य जेनेरिक तरीकों पर किस सामान्य तर्क का उपयोग करना चाहिए, लेकिन अब मुझे एक ऐसा डिज़ाइन मिला है जहां सी # कंपाइलर सफल नहीं होता है, जबकि मुझे लगता है कि यह खोजने में सफल हो सकता है सही प्रकारसी # मेरे सामान्य प्रकार का अनुमान क्यों नहीं लगाता है?
क्या कोई मुझे बता सकता है कि संकलक इस मामले में थोड़ा गूंगा है, या क्या कोई स्पष्ट कारण है कि यह मेरे सामान्य तर्कों का अनुमान नहीं लगा सकता है?
कोड यह रहा:
वर्ग और इंटरफ़ेस परिभाषाएँ:
interface IQuery<TResult> { }
interface IQueryProcessor
{
TResult Process<TQuery, TResult>(TQuery query)
where TQuery : IQuery<TResult>;
}
class SomeQuery : IQuery<string>
{
}
कुछ कोड है कि संकलन नहीं करता है:
class Test
{
void Test(IQueryProcessor p)
{
var query = new SomeQuery();
// Does not compile :-(
p.Process(query);
// Must explicitly write all arguments
p.Process<SomeQuery, string>(query);
}
}
ऐसा क्यों है? मुझे यहां क्या समझ नहीं आ रहा है?
विधि IQueryProcessor.Process (TQuery) के लिए प्रकार तर्क के उपयोग से नहीं लगाया जा सकता:
यहाँ संकलक त्रुटि संदेश (यह हमारी कल्पना के लिए बहुत कुछ नहीं छोड़ता) है। स्पष्ट रूप से प्रकार तर्कों को निर्दिष्ट करने का प्रयास करें।
कारण मेरा मानना है कि सी # यह अनुमान लगाने के लिए सक्षम होना चाहिए निम्नलिखित की वजह से है:
- मैं एक वस्तु है कि
IQuery<TResult>
लागू करता है की आपूर्ति। - यह केवल
IQuery<TResult>
संस्करण जो लागू करता हैIQuery<string>
है और इस प्रकार TResultstring
होना चाहिए। - इस जानकारी के साथ संकलक ट्रेशल्ट और TQuery है।
public interface IQueryProcessor { TResult Process<TResult>(IQuery<TResult> query); } // Implementation sealed class QueryProcessor : IQueryProcessor { private readonly Container container; public QueryProcessor(Container container) { this.container = container; } public TResult Process<TResult>(IQuery<TResult> query) { var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult)); dynamic handler = container.GetInstance(handlerType); return handler.Handle((dynamic)query); } }
IQueryProcessor
इंटरफेस अब एकIQuery<TResult>
पैरामीटर में लेता है:
समाधान
मेरे लिए सबसे अच्छा समाधान IQueryProcessor
इंटरफेस बदल सकते हैं और कार्यान्वयन में गतिशील टाइपिंग उपयोग करने के लिए किया गया था। इस तरह यह TResult
वापस कर सकता है और इससे उपभोक्ता के दृष्टिकोण से समस्याएं हल हो जाएंगी। वास्तविक कार्यान्वयन के लिए हमें कार्यान्वयन में प्रतिबिंब का उपयोग करने की आवश्यकता है, क्योंकि कंक्रीट क्वेरी प्रकारों की आवश्यकता है (मेरे मामले में)। लेकिन यहां बचाव के लिए गतिशील टाइपिंग आता है जो हमारे लिए प्रतिबिंब करेगा। आप इस article में इसके बारे में अधिक पढ़ सकते हैं।
त्रुटि संदेश क्या है:
मेरा प्रासंगिक लेख पढ़ने के लिए नहीं बल्कि यह एक है? –
कंपाइलर को पता नहीं है कि 'TResult' का उपयोग करने के लिए क्या है। उस समय इसे निर्णय लेने की आवश्यकता होती है, यह नहीं जानता कि आप इसे 'स्ट्रिंग' में डाल देंगे (इसलिए शायद इसे 'स्ट्रिंग' अनुमानित करना चाहिए)।और यहां तक कि अगर यह पता था, तो यह कानूनी रूप से 'प्रक्रिया' हो सकता है, जहां 'customClass'' स्ट्रिंग' से प्राप्त कोई भी वर्ग है। यह भी देखें: [रिटर्न टाइप अनुमान सदस्य समूहों पर काम नहीं करता है] (http://blogs.msdn.com/b/ericlippert/archive/2007/11/05/c-3-0-return-type-inference- करता है-नहीं-काम-ऑन-सदस्य-groups.aspx)। –
और @ रेमंड कहते हैं कि वह एक .NET लड़का नहीं है ... pshaw –