2009-11-12 16 views
11

मैं सी # में निम्नलिखित है:रनटाइम पर किसी अज्ञात प्रकार का उदाहरण कैसे उत्पन्न करें?

string typename = "System.Int32"; 
string value = "4"; 

शोध करे दो स्ट्रिंग निर्दिष्ट मान के साथ निर्दिष्ट प्रकार का ऑब्जेक्ट उत्पन्न करने के लिए लिया जाना चाहिए ...

परिणाम होना चाहिए:

object o = CreateUnknownType(typename, value); 
... 
Int32 test = (Int32)o; 
+4

और आपका प्रश्न है? अज्ञात बनाने का प्रयास क्यों करें यदि आप इसे किसी ज्ञात प्रकार में बाद में डालने जा रहे हैं? – Lazarus

+6

प्रश्न है: रनटाइम पर किसी अज्ञात प्रकार का उदाहरण कैसे उत्पन्न करें? इससे कोई फर्क नहीं पड़ता कि क्यों या wyh नहीं, मैं सिर्फ यह जानना चाहता हूं कि यह संभव है – haze4real

+2

यह आसान है, हां यह संभव है। क्या यह व्यावहारिक है? शायद ऩही। क्या आपका उदाहरण कुछ संदर्भ के लिए पूछना अनुचित था जब आपका उदाहरण समझ में नहीं आता? – Lazarus

उत्तर

20

क्या आप सोच रहे हैं?

object result = Convert.ChangeType("4", Type.GetType("System.Int32")); 
+0

हाँ, यह है, धन्यवाद – haze4real

1

आपका तर्क यहां थोड़ा सा दोषपूर्ण लगता है। जाहिर है, यदि आप सीधे बाद में वास्तविक प्रकार के ऑब्जेक्ट को कास्टिंग कर रहे हैं, तो आपको इसके साथ शुरू करने के प्रकार को जानना चाहिए।

यदि इस प्रश्न से कुछ और गायब है तो कृपया विस्तृत करें और शायद यह तुलना में अधिक उचित उत्तर है, "यह अधिक समझ में नहीं आता है।"

0

यह Int32.Parse (स्ट्रिंग) के लिए एक नौकरी की तरह लगता है। लेकिन दूसरों से सहमत होने के लिए ऐसा लगता है कि यह "अद्वितीय" है और शायद दस्ताने को सोचना चाहिए।

15

जैसा कि कहा गया है, यह बहुत व्यापक है और इसे हल नहीं किया जा सकता है।

Type type = Type.GetType(typename); 
object o = Activator.CreateInstance(type); 

इस प्रकार का है कि typename वर्णन है का एक उदाहरण बना देगा:

यहाँ कुछ विकल्प हैं। यह उस प्रकार के पैरामीटर रहित कन्स्ट्रक्टर को कॉल करता है। (नकारात्मक पक्ष: नहीं सभी वस्तुओं को एक parameterless निर्माता है इसके अलावा, यह value का उपयोग कर वस्तु के राज्य की स्थापना की है।।)

Type type = Type.GetType(typename); 
object o = Activator.CreateInstance(type, new[] { value }); 

इस प्रकार का है कि typename वर्णन है का एक उदाहरण का निर्माण करेगा। यह उस प्रकार का एक कन्स्ट्रक्टर कहता है जो string प्रकार के एक पैरामीटर को स्वीकार करता है। (नकारात्मक पक्ष: नहीं सभी वस्तुओं इस तरह के एक निर्माता है उदाहरण के लिए, Int32 इस तरह के एक निर्माता नहीं है तो आप एक क्रम अपवाद का अनुभव होगा।।)

Type type = Type.GetType(typename); 
object o = Convert.ChangeType(value, type); 

इस का एक उदाहरण के लिए स्ट्रिंग value परिवर्तित करने का प्रयास करेंगे आवश्यक प्रकार इससे InvalidCastException एस हो सकता है। उदाहरण के लिए, Convert.ChangeType("4", typeof(FileStream)) स्पष्ट रूप से विफल हो जाएगा, जैसा कि इसे करना चाहिए।

असल में, यह आखिरी उदाहरण (स्ट्रिंग "4" द्वारा निर्धारित प्रारंभिक स्थिति के साथ FileStream प्रकार का उदाहरण बनाएं) दिखाता है कि सामान्य समस्या कितनी बेतुका है। कुछ निर्माण/रूपांतरण हैं जो अभी नहीं किए जा सकते हैं।

आप इस मोरस से बचने के लिए हल करने की कोशिश कर रहे समस्या को पुनर्विचार करना चाहेंगे।

string typeName = "System.Int32"; 
    Type type = Type.GetType(type); 
    object o = Activator.CreateInstance(type); 

एक स्ट्रिंग से कोई मान पार्स स्पष्ट रूप से केवल प्रकार की एक सीमित सेट के लिए काम करेंगे:

+0

शायद मुझे संभावनाओं को समझाने के लिए धन्यवाद चाहिए ... – haze4real

3

नाम से एक प्रकार क्या आप जानते हैं का एक उदाहरण बनाना (और एक डिफ़ॉल्ट निर्माता है चाहिए)।आप

  • उपयोग Convert.ChangeType सुझाव दिया जा सकता था के रूप में PhilipW
  • द्वारा
  • या शायद एक Dictionary<Type,Func<string,object>> नक्शे जो जाना जाता पार्स करने के लिए जाना जाता है प्रकार कार्यों
  • या उपयोग प्रतिबिंब पार्स आह्वान करने के लिए बनाने के (स्ट्रिंग) विधि इस प्रकार, मानते हैं कि एक है:

    string valueText = "4"; 
        MethodInfo parseMethod = type.GetMethod("Parse"); 
        object value = parseMethod.Invoke(null, new object[] { valueText }); 
    
  • या हो सकता है कि आप .NET घटक मॉडल द्वारा प्रदत्त आधारभूत संरचना का उपयोग कर सकें। आप एक घटक के प्रकार कनवर्टर लाने और उपयोग कर सकते हैं यह इस तरह है:

    TypeConverter converter = TypeDescriptor.GetConverter(type); 
        object value = converter.ConvertFromString(valueText); 
    
0

इस्तेमाल करने के बाद:

public static class ReflectionExtensions 
{ 
    public static T CreateInstance<T>(this Type source, params object[] objects) 
     where T : class 
    {    
     var cons = source.GetConstructor(objects.Select(x => x.GetType()).ToArray()); 
     return cons == null ? null : (T)cons.Invoke(objects); 
    } 
} 

आशा:

Type type = Type.GetType(typename); 

इस विस्तार विधि का प्रयास करें इससे मदद मिलती है।

1

शायद आपके पास विभिन्न प्रकारों का एक सेट है, जिनमें से सभी ज्ञात इंटरफ़ेस को कार्यान्वित करते हैं?

उदाहरण के लिए यदि आपके पास कई अलग-अलग उपयोगकर्ता नियंत्रण हैं और उनमें से एक को कंटेनर में लोड करना चाहते हैं, तो प्रत्येक व्यक्ति IMyWobblyControl (एक ज्ञात इंटरफ़ेस) को कार्यान्वित कर सकता है, फिर भी आप शायद तब तक नहीं जानते जब तक कि उनमें से रनटाइम लोड न हो, संभवतः पढ़ने से विन्यास फाइल के कुछ रूप से तार।

उस स्थिति में, आपको वास्तविक असेंबली नाम की तरह वास्तविक प्रकार को लोड करने के लिए प्रतिबिंब का उपयोग करने की आवश्यकता होगी, फिर इसे अपने ज्ञात प्रकार में उपयोग करने के लिए इसे कास्ट करें।

बेशक, आप सुनिश्चित करें कि आपके कोड अमान्य डाली संभालती बनाने की जरूरत है, विधानसभा नहीं मिला और अन्य अपवाद है कि इस के रूप में के रूप में दिखता जारी कुछ के माध्यम से साथ आ जाने की संभावना है की किसी भी ...

0

यहाँ एक विशिष्ट है Azure SQL Federations को शामिल करने वाली समस्या का उदाहरण ... जो डेटा को एक अलग श्रेणी के अनुसार अलग डीबी में विभाजित करता है।

कुंजी रेंज प्रकार हैं:

एसक्यूएल/नेट एसक्यूएल प्रकार/CLR नेट

INT/SqlInt32/Int32, Nullable

BIGINT/SqlInt64/Int64 , Nullable

UNIQUEIDENTIFIER/SqlGuid/Guid, Nullable

VARBINARY (एन), अधिकतम एन 900/SqlBytes, SqlBinary/बाइट []

आदर्श रूप में, एक सी # समारोह परम या तो नेट एसक्यूएल प्रकार या CLR नेट प्रकार लेकिन प्रकार का सिर्फ एक वर्ग को व्यवस्थित ले सकता है ठीक है।

क्या "ऑब्जेक्ट" टाइप परम जाने का तरीका होगा? और, क्या इस प्रकार की पहचान करने और तदनुसार इसे बदलने का एक व्यवहार्य तरीका है?

अवधारणा है की तरह कुछ:

सार्वजनिक शून्य fn (वस्तु obj, स्ट्रिंग fedName, स्ट्रिंग distName, bool filteringOn)

{

... यह पता लगाने किस प्रकार obj सुनिश्चित करने के लिए है यह स्वीकार्य प्रकारों में से एक है ...

स्ट्रिंग कुंजी = obj.toString();

रिटर्न स्ट्रिंग। फ़ार्मेट ("उपयोग करें {0} ({1} = '{2}') रीसेट, फ़िल्टरिंग = {3}", fedName, distName, key, (filteringOn? "चालू": " बंद "));

}

हालांकि परम मूल्य स्ट्रिंग के लिए डाली है, यह फिर से पात्र चयन किया जाएगा/एसक्यूएल सर्वर साइड इसलिए एप्लिकेशन तरफ मान्य वांछित है पर जाँच की।

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

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