2013-08-09 2 views
10

मुझे निम्न समस्या है: मैं अपने पोर्टेबल क्लास लाइब्रेरी को .NET 4.5, Windows Phone 8 और Windows 8 Store Apps को लक्षित करने के लिए Delegate.CreateDelegate पर कॉल करना चाहता हूं, लेकिन मेरा कोड संकलित नहीं होता है। कंपाइलर का कहना है कि यह Delegate प्रकार पर विधि नहीं ढूंढ सकता है।मैं पोर्टेबल क्लास लाइब्रेरी में डेलीगेट क्यों कर सकता हूं। क्रेते डेलीगेट?

मजाकिया बात यह है कि उदा। माइक्रोसॉफ्ट द्वारा PRISM लाइब्रेरी पोर्टेबल क्लास लाइब्रेरी से 'Delegate.CreateDelegate' को कॉल कर सकती है। यह DelegateReference कक्षा में ऐसा करता है। PRISM पोर्टेबल क्लास लाइब्रेरी .NET 4.0, विंडोज 8 स्टोर ऐप, विंडोज फोन 8 और सिल्वरलाइट 5 (और इस प्रकार एक और अधिक प्रतिबंधक सेट) को लक्षित करता है।

कोड है कि इस तरह दिखता है संकलन नहीं करता है:

public class MyClass 
{ 
    public void MyMethod<T>(EventHandler handler) 
    { 
     var @delegate = Delegate.CreateDelegate(typeof (OpenEventHandler<T>), null, handler.GetMethodInfo()); 
    } 
} 

public delegate void OpenEventHandler<in T>(T target, object sender, EventArgs arguments); 

एक उदाहरण यहाँ डाउनलोड किया जा सकता है: https://dl.dropboxusercontent.com/u/14810011/PortableClassLibraryReferenceProblem.zip

यह मेरी पुस्तकालय परियोजना और केवल युक्त प्रिज्म PubSubEvents परियोजना का एक बहुत ही छीन संस्करण शामिल DelegateReference कक्षा और इसका इंटरफ़ेस। उत्तरार्द्ध का पूरा स्रोत कोड यहां पाया जा सकता है: http://prismwindowsruntime.codeplex.com/SourceControl/latest

सभी Delegate सदस्यों का उपयोग करने के लिए मैं क्या कर सकता हूं? आपकी मदद के लिए अग्रिम धन्यवाद!

संपादित हेंक Holterman के जवाब के बाद:

GetMethodInfo() कि पीसीएल सबसेट द्वारा समर्थित है एक विस्तार विधि है। वैसे भी, यह समस्या से संबंधित नहीं है कि मैं Delegate.CreateDelegate पर कॉल नहीं कर सकता, जबकि PRISM की पीसीएल परियोजना कर सकती है।

Picture of code that does not compile

संपादित 2 के बाद हंस Passants टिप्पणी:

मैं सिर्फ चारों ओर खेला और पता चला कि जब मैं पोर्टेबल पुस्तकालय का एक लक्ष्य के रूप में Silverlight 5 सक्रिय करें, फिर Delegate.CreateDelegate वास्तव में पहुँचा जा सकता है (और GetMethodInfo एक्सटेंशन विधि अब नहीं है)। Delegate.CreateDelegate है तो शायद विंडोज 8 स्टोर और फोन ऐप के लिए आंतरिक रूप से किसी अन्य एपीआई में मैप किया गया हो? यह एकमात्र तरीका है जिसके बारे में मैं सोच सकता हूं कि इस विधि को अचानक कैसे पहुंचाया जा सकता है क्योंकि मैंने सिल्वरलाइट 5 को वैध लक्ष्य के रूप में जोड़ा है।

(आप "MyPortableClassLibrary" परियोजना पर राइट-क्लिक करके इस पुन: पेश, "गुण" पर क्लिक करें और "पुस्तकालय" टैब पर क्लिक करें परिवर्तन में चौखटे कि पोर्टेबल पुस्तकालय द्वारा लक्षित कर रहे हैं का चयन कर सकते हैं।)

इसके अलावा, आज के पहले, मैंने एक विंडोज स्टोर ऐप प्रोजेक्ट बनाया और देखा कि CreateDelegate विधि Delegate क्लास पर Windows Runtime के लिए .NET में परिभाषित विधि थी।

मेरी वास्तविक परियोजना में, मैं सिल्वरलाइट 5 को लक्षित नहीं करना चाहता क्योंकि मैं IObservable<T> और IObserver<T> का उपयोग आरएक्स का उपयोग करके भारी रूप से करता हूं और इन इंटरफेस को सिल्वरलाइट में परिभाषित नहीं किया जाता है।

+1

मेरी मशीन पर ठीक काम करता है। –

+0

@ हंस मुझे पता है कि आपने नमूना कोड डाउनलोड नहीं किया है? क्योंकि यह वहां काम नहीं कर रहा है। वैसे भी, मैंने अपने हालिया निष्कर्षों पर अपना प्रश्न अपडेट किया। – feO2x

+1

यह पोर्टेबल पुस्तकालयों में एक समस्या है, कुछ सबसेट अलग-अलग एपीआई देते हैं, यह मुझे कुछ प्रतिबिंब प्रकारों के साथ हुआ जो कि विंडोज 8/फोन सबसेट पर उपलब्ध नहीं थे जब तक कि मैंने सिल्वरलाइट को लक्षित नहीं किया। – Rafael

उत्तर

10

क्या जब आप जोड़ें/निकालें सिल्वरलाइट आप देख रहे हैं, पोर्टेबल है दो अलग .NET एपीआई सतह क्षेत्रों के बीच flipping। मैं इन दो अलग-अलग सतह क्षेत्रों को यहां कवर करता हूं: What is .NET Portable Subset (Legacy)?

जिसे हम विरासत सतह क्षेत्र कहते हैं, यह विधि प्रतिनिधि पर रहती है। नए सतह क्षेत्र में, यह विधि MethodInfo में ले जाया गया है।

हमने ऐसा क्यों किया?

परतों के कारणों के लिए। नई सतह में, प्रतिबिंब प्रकार (यानी असेंबली, सदस्यइन्फो, मेथडइन्फो, आदि) कोर प्राइमेटिव्स की तुलना में उच्च परत में रहने के रूप में माना जाता है, जिसमें प्रतिनिधि शामिल है। विरासत सतह क्षेत्र के विपरीत (जहां वे सभी mscorlib में रहते हैं), इन प्रकारों को विभिन्न असेंबली में; क्रमशः System.Reflection.dll और System.Runtime.dll।

यह विधि (कुछ अन्य) एक उच्च परत (System.Runtime.dll) पर कुछ पर निर्भर करने के लिए निम्न परत (System.Runtime.dll) पर कुछ उत्पन्न कर रही थी। इसे रोकने के लिए, निर्भरता उलट दी गई थी।

+0

अतिरिक्त अंतर्दृष्टि, डेविड के लिए धन्यवाद। – feO2x

11

ठीक है, सोने की रात के बाद, मुझे पता चला कि मेरा प्रश्न वास्तव में होना चाहिए "मैं विंडोज रनटाइम के साथ पेश की गई नई एपीआई में प्रतिनिधियों को गतिशील रूप से कैसे बना सकता हूं?"। जैसा कि राफेल ने मेरे प्रश्न की टिप्पणियों में संकेत दिया था, विंडोज 8/फोन 8 को .NET के अतिरिक्त लक्षित करते समय विभिन्न एपीआई प्रदान की जाती हैं।यदि सिल्वरलाइट को भी लक्षित किया गया है, तो एपीआई जो विंडोज 8/फोन 8 में उपलब्ध नहीं हैं, मैप किए जाएंगे और यह बताता है कि जब मैं पोर्टेबल क्लास लाइब्रेरी के लक्ष्य के रूप में सिल्वरलाइट जोड़ता हूं तो मैं अचानक Delegate.CreateDelegate पर कॉल क्यों कर सकता हूं। .NET में, प्रतिबिंब के लिए नए एपीआई .NET 4.5 के साथ पेश किए गए थे।

वैसे भी, Windows में एक प्रतिनिधि बनाने के लिए 8/Windows Phone 8, एक सिर्फ इस तरह, MethodInfo.CreateDelegate विधि का उपयोग करना पड़ता है:

public class MyClass 
{ 
    public void MyMethod<T>(EventHandler handler) 
    { 
     var methodInfo = handler.GetMethodInfo(); 
     var @delegate = methodInfo.CreateDelegate(typeof(OpenEventHandler<T>), null); 
    } 
} 

public delegate void OpenEventHandler<in T>(T target, object sender, EventArgs arguments); 
संबंधित मुद्दे