2011-12-24 19 views
10

मेरे पास एक वर्ग के कुछ चर होते हैं, और प्रत्येक पंक्ति एक जोड़ी है: चर, मूल्य। मैं प्रतिबिंब का उपयोग कर रनटाइम (ए-ला XmlSerializer) पर लोड करने का एक तरीका ढूंढ रहा हूं।सी # पार्स स्ट्रिंग रनटाइम पर ज्ञात टाइप करने के लिए

string को Type पर केवल रनटाइम पर जाने के लिए कोई तरीका है? क्योंकि PropertyType वर्ग Type जो एक सामान्य Parse() विधि नहीं है की है

निम्नलिखित, एक इच्छाधारी कोड नमूना जहां आखिरी पंक्ति (pi.SetValue() साथ सही नहीं है।

using (var sr = new StreamReader(settingsFileName)) 
{ 
    String line; 
    while ((line = sr.ReadLine()) != null) 
    { 
     String[] configValueStrs = line.Trim().Split(seps); 

     PropertyInfo pi = configurableProperties 
       .Single(p => p.Name == configValueStrs[0].Trim()); 

     //How do I manage this? 
     pi.SetValue(this, pi.PropertyType.Parse(configValueStrs[1].Trim()), null); 
    } 
} 
प्रासंगिक के सभी के बाद से

चर Ints, डबल्स, तार या Booleans, एक अंतिम उपाय के रूप में कर रहे हैं, मैं प्रकार पर स्विच और इसी ToType() विधि का उपयोग कर सकते हैं, लेकिन मुझे यकीन है कि वहाँ एक और अधिक सुरुचिपूर्ण समाधान है।

उत्तर

7

आपको लगता है कि के लिए स्थिर Convert.ChangeType विधि का उपयोग कर सकते हैं। यह ऑब्जेक्ट को अपना पहला पैरामीटर और Type उदाहरण के रूप में लेता है जिसे आप ऑब्जेक्ट को कन्वर्ट करना चाहते हैं। रिटर्न वैल्यू उस प्रकार का है जिसे आपने अनुरोध किया है या शून्य है यदि कोई उपयुक्त रूपांतरण नहीं मिला है। यह विधि 4 अलग-अलग अपवादों को फेंक देती है, जिनमें से तीन उस मूल्य के कारण होते हैं जो इसे बदलने की कोशिश करता है। आप इन्हें पकड़ना और संभालना चाहते हैं।

अपने उदाहरण में इस प्रकार समारोह का उपयोग करें:

// Convert.ChangeType can throw if the string doesn't convert to any known type 
    pi.SetValue(this 
     , Convert.ChangeType(configValueStrs[1], pi.PropertyType) 
     , null); 
2

मुझे विश्वास है कि TypeConverters, विशेष रूप से StringConverter इस समस्या से आपकी मदद कर सकते हैं।

http://msdn.microsoft.com/en-us/library/system.componentmodel.stringconverter.aspx

+0

चेक इस: http: //chrismarinos.com/default-typeconverters-and-objects/ इसके अलावा अपने अनुभव में, डिफ़ॉल्ट कार्यान्वयन कुछ भी नहीं कर सकता है। – Peter

17

TypeConverters जाने का रास्ता है। क्या करना है इसके अच्छे उदाहरण के लिए here पर एक नज़र डालें।

सीधे hanselmans ब्लॉग से nicked:

public static T GetTfromString<T>(string mystring) 
{ 
    var foo = TypeDescriptor.GetConverter(typeof(T)); 
    return (T)(foo.ConvertFromInvariantString(mystring)); 
} 
+0

इस पर +1 है क्योंकि यह GUIDS को नियंत्रित करेगा, कनवर्ट करें। चेंजटाइप – Arical

+0

धन्यवाद नहीं, मुझे चिपचिपा स्थिति से बाहर करने में मदद मिली! – Peter

-2

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

संक्षेप में, मैं निम्नलिखित कोड का उपयोग (विधि FieldInfo.SetValue (Object, Object) कुंजी यहाँ है, क्योंकि यह Object मूल्य के किसी भी प्रकार के रूपांतरण, TypeConverter.ConvertFromString विधि द्वारा वापस की आवश्यकता नहीं है है):

using System.Reflection; 
using System.ComponentModel; 
using System.Globalization; 

.... 

Settings settings = new Settings(); // my Settings class with variables to load 
FieldInfo[] fields = settings.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static); 
.... 

foreach (var field in fields) 
{ 
    if (key.KeyName == field.Name) 
    { 
     try 
     { 
      field.SetValue(settings, TypeDescriptor.GetConverter(field.FieldType).ConvertFromString(null, CultureInfo.InvariantCulture, key.Value)); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Error: The value string \"{0}\" isn't parsed!", key.Value); 
      //Console.WriteLine(ex.ToString()); 
     } 
     break; 
    } 
} 
संबंधित मुद्दे