आप कंपाइलर को प्रकार पैरामीटर का अनुमान लगाने की अनुमति दे रहे हैं। इस मामले में 1 के लिए ठीक काम करता है:
class SomeClass<T> where T : class {
void SomeMethod<TProperty>(Expression<Func<T,TProperty>> expression){ ... }
}
क्योंकि आप पहली बार एक उदाहरण की घोषणा:
var sc = new SomeClass<MyDateClass>();
जो संकलक कि T is MyDateClass
बताता है। फिर, जब आप विधि कॉल:
sc.SomeMethod(dt => dt.Year);
संकलक जानता है कि T is MyDateClass
, तो T.Year
किसी पूर्णांक होना चाहिए। SomeMethod
को SomeMethod<MyDateClass, int>
के रूप में हल करने के लिए पर्याप्त जानकारी है।
आपका दूसरे उदाहरण है, तथापि, स्पष्ट रूप से प्रकार पैरामीटर (रों) बताते हुए है - को संकलक बता यह अनुमान नहीं लगा:
sc.SomeMethod<MyDateClass>(dt => dt.Year);
दुर्भाग्य से, यह केवल एक ही प्रकार के साथ SomeMethod
कॉल करने के लिए कोशिश कर रहा है पैरामीटर (<MyDateClass>
बिट)। चूंकि यह अस्तित्व में नहीं है, यह शिकायत करेगा और कहेंगे कि आपको 2 प्रकार के पैरामीटर की आवश्यकता है।
, तो इसके बजाय, आप इसे कॉल करने के लिए थे, जैसे आप पहले उदाहरण किया:
sc.SomeMethod(dt => dt.Year);
संकलक, शिकायत करेगा जो आपको बताएगा कि यह प्रकार पैरामीटर अनुमान नहीं लगा सकता - वहाँ बस नहीं है क्या यह निर्धारित करने के लिए पर्याप्त जानकारी dt
है। तो, आप स्पष्ट रूप से यह कर सकता है दोनों प्रकार पैरामीटर:
sc.SomeMethod<MyDateClass, int>(dt => dt.Year);
या, संकलक है क्या dt
बता (राशि है जो आप Newing SomeClass<MyDateClass>
से पहले उदाहरण में किया था):
sc.SomeMethod((MyDateClass dt) => dt.Year);
संपादित करता और अपडेट:
तो प्रभावी ढंग से संकलक पहले उदाहरण में जादू कर रहा है? एक धारणा बनाना कि टीप्रोपर्टी एक int होना चाहिए क्योंकि। एक int int है? यह मेरे प्रश्न का उत्तर देगा, यह नहीं कह सकता कि यह संतोषजनक है।
वास्तव में जादू नहीं है, लेकिन छोटे चरणों की एक श्रृंखला है।illustate करने के लिए:
sc
प्रकार SomeClass<MyDateClass>
की है, T = MyDateClass
SomeMethod
बनाने dt => dt.Year
की एक पैरामीटर के साथ कहा जाता है।
dt
होना चाहिए एक टी (SomeMethod
कैसे परिभाषित किया जाता है कि) है, जो होना चाहिए उदाहरण sc
के लिए एक MyDateClass
।
dt.Year
एक int होना चाहिए, क्योंकि MyDateClass.Year
एक int घोषित किया गया है।
dt => dt.Year
के बाद से हमेशा किसी पूर्णांक, expression
की वापसी वापसी पूर्णांक होना चाहिए होगा। इसलिए TProperty = int
।
- यह पैरामीटर
expression
से SomeMethod
, Expression<Func<MyDateClass,int>>
बनाता है। याद रखें कि T = MyDateClass
(चरण 1), और TProperty = int
(चरण 5)।
- अब हमने
SomeMethod<T, TProperty>
= SomeMethod<MyDateClass, int>
बनाने के सभी प्रकार के पैरामीटर का पता लगाया है।
[बी] ut क्या श्रेणी स्तर पर टी निर्दिष्ट करने और विधि के स्तर पर निर्दिष्ट करने के बीच का अंतर है? SomeClass<SomeType>
बनाम SomeMethod<SomeType>
... दोनों मामलों में टी ज्ञात है ना?
हाँ, T
दोनों मामलों में जाना जाता है। समस्या यह है कि SomeMethod<SomeType>
केवल एक ही प्रकार के पैरामीटर के साथ एक विधि कॉल करता है। उदाहरण 2 में, प्रकार पैरामीटर हैं। आप या तो संकलक infer सभी विधि के लिए पैरामीटर पैरामीटर या उनमें से नहीं कर सकते हैं। आप केवल 1 पास नहीं कर सकते हैं और इसे दूसरे (TProperty
) का अनुमान लगा सकते हैं। इसलिए, यदि आप स्पष्ट रूप से T
बताएंगे, तो आपको स्पष्ट रूप से TProperty
भी अवश्य बता देना चाहिए।
तो प्रभावी ढंग से संकलक पहले उदाहरण में जादू कर रहा है? एक धारणा बनाना कि टीप्रोपर्टी एक int होना चाहिए क्योंकि। एक int int है? यह मेरे प्रश्न का उत्तर देगा, यह नहीं कह सकता कि यह संतोषजनक है। :) –
... मुझे लगता है कि प्रकाश बस चला गया। कक्षा और विधि के बीच अंतर यह है कि कक्षा का तात्पर्य है कि टी का एक उदाहरण संदर्भ में मौजूद है जबकि विधि नहीं है? इसलिए संकलक द्वारा धारणाएं? –
सुनिश्चित नहीं है कि आप संतुष्ट क्यों नहीं हैं, लेकिन स्थिर प्रकार का संदर्भ कोई जादू नहीं है, और इसमें स्पष्ट नियम हैं और सी # में एक नई सुविधा है। –