2010-03-02 18 views
19

कई जगहों पर मुझे फॉर्म FullTypeName, AssemblyName के आंशिक रूप से योग्य प्रकार के नाम मिलते हैं, यानी Type.AssemblyQualifiedName केवल संस्करण, संस्कृति और सार्वजनिक केकटाउन क्वालीफायर के बिना।आंशिक रूप से योग्य प्रकार के नाम दिए जाने पर टाइप टाइप। गेट टाइप टाइप करता है?

मेरा प्रश्न यह है कि कम से कम प्रयास में इसे Type में कैसे परिवर्तित किया जा सकता है? मैंने सोचा कि Type.GetType नौकरी करता है, लेकिन हां, ऐसा नहीं है। निम्नलिखित कोड, उदाहरण के लिए, रिटर्न null:

Type.GetType("System.Net.Sockets.SocketException, System"); 
बेशक

, अगर मैं पूरी तरह से योग्य नाम यह काम करता है निर्दिष्ट करें:

Type.GetType("System.Net.Sockets.SocketException, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 

धन्यवाद एक बहुत।

+0

क्या आपके पास संकलन समय पर प्रकार है? यदि ऐसा है तो टाइपफ़ोफ़ का उपयोग क्यों न करें ()। FullName, et। अल? यदि आपके पास रनटाइम पर प्रकार है तो आप का उपयोग कर सकते हैं .GetType()। FullName et। अल। या क्या मैं विशिष्ट अनुरोध खो रहा हूं? मुझे लगता है कि आप केवल आंशिक नाम निर्दिष्ट करना चाहते हैं, लेकिन लोडर के लिए यह वास्तव में अधिक है क्योंकि यह सिस्टम सिस्टम के लिए है। एफक्यूएन दुर्लभ अवसरों के लिए संदर्भ मुद्दों को असंबद्ध करने के लिए हैं जहां नाम विवाद होते हैं, जो कि बीसीएल असेंबली की तुलना में उपयोगकर्ता असेंबली में सचमुच अधिक होता है। – GrayWizardx

+1

मैं टाइपऑफ() या Type.FullName के बारे में पूरी तरह से अवगत हूं। ऑब्जेक्ट का प्रकार कॉन्फ़िगरेशन फ़ाइल से पढ़ा जाता है, इसलिए मैं Type.GetType का उपयोग करता हूं। और यही कारण है कि मुझे समझने में इतनी दिलचस्पी है कि आंशिक रूप से योग्य प्रकार के नाम कैसे काम करते हैं। – mark

उत्तर

8

यदि डीएलएल में यह पहले से ही एप्लिकेशन डोमेन में लोड नहीं हुआ है (उदाहरण के लिए आपने इसका उपयोग किया है), तो आपको इस तरह का पूरा पथ चाहिए, अगर यह पहले से लोड हो चुका है, तो यह इसे छोटे संस्करण के साथ मिल सकता है।

अपने प्रश्न का उत्तर देने के लिए: दूसरा संस्करण हमेशा काम करता है, इसके साथ चिपके रहें और आपके पास चिंता करने का एक तरीका है।

+1

मुझे नहीं लगता कि यह महत्वपूर्ण है कि असेंबली पहले ही लोड हो चुकी है या नहीं - लघु संस्करण काम नहीं करेगा। नामस्थान-योग्य नाम काम करेगा यदि प्रकार वर्तमान में निष्पादित असेंबली में या mscorlib में है। नीचे फुलर स्पष्टीकरण। – lesscode

2

कोड संक्षिप्त रूप के साथ काम कर रहा है:

Assembly a = Assembly.LoadWithPartialName(assemblyName); 
    Type t = a.GetType(typeName); 

लेकिन LoadWithPartialName हटाई गई है, इसलिए मुझे लगता है कि आप लंबे समय फार्म के साथ चिपके रहते हैं चाहिए।

29

विधानसभा वर्तमान डोमेन लोड किया गया है, तो आमतौर पर नीचे दिए गए कोड काम करता है:

public static Type GetTypeEx(string fullTypeName) 
{ 
    return Type.GetType(fullTypeName) ?? 
      AppDomain.CurrentDomain.GetAssemblies() 
        .Select(a => a.GetType(fullTypeName)) 
        .FirstOrDefault(t => t != null); 
} 

आप यह इतना की तरह उपयोग कर सकते हैं:

Type t = GetTypeEx("System.Net.Sockets.SocketException"); 
+1

इस उत्तर के लिए बहुत बहुत धन्यवाद! यह वही है जो मैं खोज रहा था - "स्वीकृत" उत्तर से काफी बेहतर। –

+2

बस याद रखें कि यह बहुत धीमा हो सकता है, इसलिए कैश करना न भूलें .. – nawfal

2

बस के साथ एक समान मुद्दा माध्यम से चले गए करने के बाद कुछ विरासत कोड, मुझे नहीं लगता कि स्वीकृत उत्तर में पहला बयान सही है। इससे कोई फर्क नहीं पड़ता कि असेंबली पहले ही लोड हो चुकी है या नहीं।

प्रलेखन के अनुसार, Type.GetType(string) को AssemblyQualifiedName की आवश्यकता होती है, जब तक कि वर्तमान में निष्पादित असेंबली या mscorlib में प्रश्न का प्रकार न हो, उस स्थिति में नामस्थान-योग्य प्रकार का नाम आवश्यक है।

ध्यान दें कि एक असेंबली क्वालिफाइडनाम में प्रकार की असेंबली (संस्करण, संस्कृति और सार्वजनिक कुंजी टोकन के साथ) का पूर्ण प्रदर्शन नाम शामिल है।

छोटा संस्करण तब तक काम नहीं करेगा जब तक आप कस्टम AssemblyResolver (जो वास्तव में मेरे मुद्दे के साथ मामला था, दूसरी समस्या का मुखौटा) के साथ असफल प्रकार लोड को रोकता है।

0

सच है, Type.GetType (स्ट्रिंग) को असेंबली क्वालिफाइडनाम की आवश्यकता होती है।यह कई रूपों में हो सकता है:

MyNS.MyType, MyAssembly, Version=x.x.x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 

निम्नलिखित भी मान्य AssemblyQualifiedNames हैं:

MyNS.MyType, MyAssembly, Version=x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly 

एक हस्ताक्षरित विधानसभा के लिए, न्यूनतम एक FullyQualifiedAssemblyName के लिए आवश्यक है:

MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 

एक के लिए हस्ताक्षरित असेंबली, फुलली क्वालिफाइडएस्क्रिप्ट्सनाम के लिए आवश्यक न्यूनतम है:

MyNS.MyType, MyAssembly 

कोड स्निपेट में चल रहे सभी "हाथ से चलने" की आवश्यकता नहीं है। सुनिश्चित करें कि आपके प्रकार के नाम ठीक से स्थापित किए गए हैं और आप उच्च स्तर की लचीलापन के साथ अपने प्रकार (और गतिशील रूप से असेंबली लोड) तक पहुंच सकते हैं। मैं यह नियमित रूप से करता हूं।

ओपी के उदाहरण में उपयोग करते हुए:

Type.GetType("System.Net.Sockets.SocketException, System") 

विफलता का कारण PublicKeyToken के अभाव था। .NET FW असेंबली सभी हस्ताक्षरित हैं और इसलिए विधानसभा नाम को हल करने के लिए PublicKeyToken की आवश्यकता है। निम्नलिखित काम करेंगे:

Type.GetType("System.Net.Sockets.SocketException, System, PublicKeyToken=b77a5c561934e089") 
संबंधित मुद्दे