2011-08-16 15 views
8

Action<T> मान सेट करते समय मुझे एक सशर्त कथन के साथ यह वास्तव में अजीब समस्या है। ऐसा नहीं है कि मुझे नहीं पता कि इस बारे में कैसे काम करना है क्योंकि सामान्य if का उपयोग कर हल करना बहुत आसान है।सशर्त कथन, जेनेरिक प्रतिनिधि अनावश्यक कास्ट

public class Test 
{ 
    public bool Foo { get; set; } 
    public Action<bool> Action { get; set; } 

    public void A() 
    { 
     Action = Foo ? B : C;//Gives compiler error 
    } 

    public void B(bool value) 
    { 

    } 

    public void C(bool value) 
    { 

    } 
} 

यह मैं संदेश

वहाँ 'विधि समूह' और 'विधि समूह' के बीच कोई अंतर्निहित रूपांतरण के साथ एक संकलक त्रुटि देता है:

यहाँ मेरी समस्या है।

जो अजीब बात है क्योंकि मुझे पता नहीं चल सकता कि यह अवैध क्यों होगा।

वैसे, नीचे वाक्य रचना कर देगा यह वैध (देखने के compilers बिंदु से):

public void A() 
    { 
     Action = Foo ? (Action<bool>) B : C; 
    } 

तो हो सकता है आप सवाल पढ़ सकते हैं के रूप में, क्यों डाली आवश्यक है?

उत्तर

2

आप दो समान अवधारणाओं conflating कर रहे हैं:

ए) एक विधि समूह। एक विधि समूह एक ही नाम के साथ एक या अधिक सी # विधियां है। यह मुख्य रूप से संकलक द्वारा उपयोग किया जाने वाला एक अमूर्त है; आप एक विधि समूह के आसपास पास नहीं कर सकते हैं। एक विधि समूह के साथ आप जो कुछ भी कर सकते हैं वह इसे आमंत्रित कर रहा है या इसके बाहर एक प्रतिनिधि बना सकता है। टाइप हस्ताक्षर मिलान होने पर आप एक विधि समूह से निहित रूप से एक प्रतिनिधि बना सकते हैं।

बी) एक प्रतिनिधि। आप जानते हैं कि एक प्रतिनिधि क्या है; इसमें एक विशिष्ट प्रकार का हस्ताक्षर है और सीधे एक विधि को संदर्भित करता है। इसके साथ-साथ इसे आमंत्रित करने के साथ, आप इसे चारों ओर पास कर सकते हैं और इसे प्रथम श्रेणी की वस्तु के रूप में देख सकते हैं।

तो पहले उदाहरण में, आपकी अभिव्यक्ति एक तरफ एक विधि समूह B और दूसरी तरफ एक अन्य विधि समूह C देता है। टर्नरी ऑपरेटर को दोनों तरफ एक ही प्रकार की वापसी की आवश्यकता होती है, लेकिन यह नहीं जानता कि दोनों तरफ से क्या करना है; वेरिएबल प्रकार जिसे आपने परिणाम सौंपा (Action<bool>) अभिव्यक्ति के प्रकार को निर्धारित नहीं करता है। तो यह संदिग्ध है।

दूसरे उदाहरण में, आपने कानूनी रूप से विधि समूह B को Action<bool> टर्नरी ऑपरेटर के एक तरफ प्रतिनिधि को कास्ट किया। अभिव्यक्ति को असंबद्ध करने की कोशिश करने की प्रक्रिया में, संकलक दूसरी तरफ दूसरी तरफ डालने की कोशिश करता है। यह विधि समूह C को Action<bool> पर सफलतापूर्वक कास्ट कर सकता है, इसलिए ऐसा होता है और अभिव्यक्ति कानूनी है।

-1

एक कार्य एक विशिष्ट प्रतिनिधि वर्ग है, और एक समान हस्ताक्षर के साथ एक नियमित प्रतिनिधि से/एक लागू रूपांतरण उपलब्ध नहीं है।

+0

मैंने सोचा कि सी # कंपाइलर यह जांचने के लिए पर्याप्त स्मार्ट है ... –

1

क्योंकि B और C वास्तव में प्रतिनिधि नहीं हैं। वे विधि समूह हैं, और उन्हें निहित रूप से प्रतिनिधियों में परिवर्तित किया जा सकता है (विशेष रूप से Action<bool>), लेकिन यह वही बात नहीं है।

सशर्त अभिव्यक्ति का प्रकार दोनों शाखाओं पर सुसंगत होना चाहिए, और B और C वर्तमान में विधि समूह (जो टाइप नहीं किए गए हैं) हैं, तो कंपाइलर यह नहीं समझ सकता कि किस प्रकार का होना चाहिए। जैसा कि यह आपको बताता है, उनके बीच कोई अंतर्निहित रूपांतरण नहीं है।

साथ ही, यह (या कम से कम नहीं है) से अधिक असाइनमेंट ऑपरेटर के दूसरी तरफ देख सकते हैं नहीं और कहते हैं कि "ओह, यह Action<bool> होना चाहिए।"

आप एक डाली जोड़ते हैं, बाईं शाखा अभिव्यक्ति के प्रकार Action<bool> हो जाता है, और वहाँ दूसरी तरफ विधि समूह और कहा कि प्रतिनिधि, तो संकलक के बीच एक अंतर्निहित रूपांतरण फिर से खुश है: के प्रकार पूरी अभिव्यक्ति Action<bool> है।

0

मुझे लगता है, Eric will again tell me, that my reasoning is slightly incorrect, लेकिन मैं एक वैसे भी कोशिश करते हैं और उसके सुधार :-)

एक विधि समूह के लिए आशा है कि, उदाहरण के B के लिए, एक प्रकार नहीं है, है ना एक वस्तु है यह दे देंगे (B.GetType() संकलन करने वाला नहीं है)।
इसे आसानी से एक प्रकार में परिवर्तित किया जा सकता है, यही कारण है कि एक अंतर्निहित कास्ट मौजूद है। नमूना:

Action<bool> a = B; // implicit cast taking place. 

हालांकि, आप लिंक किए गए सवाल में देख सकते हैं, त्रिगुट अभिव्यक्ति एक वापसी प्रकार खोजने की कोशिश करता है कि अभिव्यक्ति मैच के दोनों भागों। यह नहीं पता कि बाद में Action<bool> में रूपांतरण होना चाहिए।चूंकि विधि समूह प्रति प्रकार नहीं हैं, उनके बीच कोई रूपांतरण नहीं है और B को C में परिवर्तित नहीं किया जा सकता है और इस प्रकार, संकलक इसके बारे में शिकायत करता है।

Action<bool> पर टर्नरी अभिव्यक्ति के किसी भी हिस्से को कास्ट करके, आप संकलक को बताते हैं कि वापसी का प्रकार उस प्रकार का होना चाहिए और यह जांचता है कि टर्नरी अभिव्यक्ति का दूसरा भाग उस प्रकार के निहित कास्ट का समर्थन करता है या नहीं। क्योंकि यह मामला है, कोड संकलित होगा।

संबंधित मुद्दे