2012-11-14 19 views
8

में कनवर्ट करें मेरे पास string और Type है, और मैं मान को उस Type में परिवर्तित करना चाहता हूं।स्ट्रिंग से किसी भी मूल प्रकार

public static object StringToType(string value, Type propertyType) 
{ 
    return Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture); 
} 

यह एक object है कि मैं एक संपत्ति निर्धारित मूल्य कॉल में उपयोग कर सकते हैं देता है:

public static void SetBasicPropertyValueFromString(object target, 
                string propName, 
                string value) 
{ 
    PropertyInfo prop = target.GetType().GetProperty(propName); 
    object converted = StringToType(value, prop.PropertyType); 
    prop.SetValue(target, converted, null); 
} 

यह सबसे बुनियादी प्रकार के लिए काम करता है, nullables को छोड़कर।

System.InvalidCastException::

[TestMethod] 
public void IntTest() 
{ //working 
    Assert.AreEqual(1, ValueHelper.StringToType("1", typeof (int))); 
    Assert.AreEqual(123, ValueHelper.StringToType("123", typeof (int))); 
} 

[TestMethod] 
public void NullableIntTest() 
{ //not working 
    Assert.AreEqual(1, ValueHelper.StringToType("1", typeof (int?))); 
    Assert.AreEqual(123, ValueHelper.StringToType("123", typeof (int?))); 
    Assert.AreEqual(null, ValueHelper.StringToType(null, typeof (int?))); 
} 

NullableIntTest साथ पहली पंक्ति पर विफल रहता है 'System.Nullable`1 करने के लिए' System.String 'से अमान्य कलाकार [[System.Int32, mscorlib, संस्करण = 4.0 .0.0, संस्कृति = तटस्थ, PublicKeyToken = b77a5c561934e089]] '।

मुझे टाइप करने में कठिनाई हो रही है अगर प्रकार शून्य है और StringToType विधि का व्यवहार बदल रहा है।

व्यवहार मैं के बाद हूँ:

तो स्ट्रिंग शून्य या खाली है, अशक्त लौटने के लिए, किसी और प्रति गैर-व्यर्थ प्रकार के रूप में परिवर्तित करते हैं।

परिणाम

किरिल के जवाब की तरह

, एक ChangeType केवल के साथ कॉल।

public static object StringToType(string value, Type propertyType) 
{ 
    var underlyingType = Nullable.GetUnderlyingType(propertyType); 
    if (underlyingType != null) 
    { 
     //an underlying nullable type, so the type is nullable 
     //apply logic for null or empty test 
     if (String.IsNullOrEmpty(value)) return null; 
    } 
    return Convert.ChangeType(value, 
           underlyingType ?? propertyType, 
           CultureInfo.InvariantCulture); 
} 
+0

आप अपने विधि सामान्य बना सकते हैं: 'जनता स्थिर वस्तु StringToType (स्ट्रिंग मान) जहां टी: struct' ... –

+0

@KarelFrajtak ना, क्योंकि जिस तरह से यह कहा जाता है की, दूसरा कोड टुकड़ा देखते हैं। 'prop.PropertyType' प्रतिबिंब से है, इसलिए रनटाइम तक ज्ञात नहीं है। – weston

+0

आपकी 'if' चेक बिल्कुल सही नहीं है। आपके विशेष मामले * किसी भी * जेनेरिक प्रकार के लिए नहीं होना चाहिए, यह * शून्य * 0N'के लिए * बस * होना चाहिए क्योंकि उन्हें अलग-अलग बॉक्स किया गया है। – Servy

उत्तर

4

आप कन्वर्ट का उपयोग नहीं कर सकते हैं। परिवर्तनीय प्रकारों पर चेंजटाइप का कारण यह आईसीओवर्टिबल से विरासत में नहीं है। आपको अपनी विधि को फिर से लिखना चाहिए।

public static object StringToType(string value, Type propertyType) 
{ 
    var underlyingType = Nullable.GetUnderlyingType(propertyType); 
    if(underlyingType == null) 
      return Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture); 
    return String.IsNullOrEmpty(value) 
      ? null 
      : Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture); 

}

2

इस प्रयास करें:

prop.IsGenericType && Nullable.GetUnderlyingType(prop) == value.GetType() 
3
public static object StringToType(string value, Type propertyType) 
{ 
    var underlyingType = Nullable.GetUnderlyingType(propertyType); 
    return underlyingType == null ? Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture) : Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture); 
} 
+0

अच्छा, शून्य या खाली तारों को संभालने के लिए बस लापता तर्क। – weston

+0

यह भी बताता है कि यह क्यों काम करता है। – Servy

+0

आपने एक अच्छा स्पष्टीकरण Servy [लिंक] लिखा है (http://stackoverflow.com/a/13381751/1173331) –

0

आप प्रत्येक प्रकार आप का समर्थन करना चाहते के लिए एक उपयुक्त कलाकारों विधि का उपयोग करना होगा।

int parsedInt; 
int.TryParse("1", out parsedInt); 

double parsedDouble; 
double.TryParse("0.0d", out parsedDouble); 

कंपाइलर स्ट्रिंग की सामग्री के आधार पर प्रकार को समझना असंभव है। स्ट्रिंग से स्केलर्स प्रकारों में कनवर्ट करने के बारे में अधिक जानकारी के लिए निम्न लिंक देखें: http://msdn.microsoft.com/en-us/library/bb397679.aspx और http://msdn.microsoft.com/en-us/library/bb384043.aspx

+0

निश्चित रूप से यह असंभव होगा, लेकिन मैं कंपाइलर को इस प्रकार काम करने के लिए नहीं कह रहा हूं। मेरे पास 'टाइप टाइप टाइप टाइप' – weston

2

समस्या है कि यहाँ ChangeType की वापसी मान, साथ ही अपने विधि, object है। जब आप object में किसी भी शून्य प्रकार को बॉक्स करते हैं तो यह शून्य प्रकार के बॉक्स को बॉक्स नहीं करता है। यदि रनटाइम पर मान वास्तव में शून्य है तो यह null पर बक्से लगाता है, और यदि उसके पास कोई मान है तो यह वास्तविक अंतर्निहित मान (शून्य संस्करण के बजाए) को बॉक्स करता है।

int? i = 5; 
object o = i; 
Type t = o.GetType();//will be `int`, not `Nullable<int>` 

यह किसी अन्य प्रकार के सामान्य मामले में नहीं होगा; Nullable<T> में ऐसा करने के लिए विशेष कंपाइलर समर्थन है।आपको मूल रूप से अपने कोड में Nullable विशेष मामले की आवश्यकता होगी; यदि आपकी विधि Nullable प्रकार से गुजरती है तो आपको पहले null के लिए ऑब्जेक्ट की जांच करनी होगी, और यदि null नहीं है, तो इसके बजाय Nullable के अंतर्निहित प्रकार का उपयोग करें।

1

किरिल Bestemyanov 'टुकड़ा की मदद से कोड:

public static object StringToType<T>(string value) 
{ 
    return StringToType(value, typeof(T)); 
} 

public static object StringToType(string value, Type propertyType) 
{ 
    var underlyingType = Nullable.GetUnderlyingType(propertyType); 
    if(underlyingType == null) 
    return Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture); 
    return String.IsNullOrEmpty(value) 
    ? null 
    : Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture); 
} 

और उपयोग (WL सिर्फ सांत्वना देने लिखते हैं)। आप सही थे, जेनेरिक विधि सामान्य पैरामीटर के रूप में int? का उपयोग नहीं कर सकती है।

WL(StringToType("1", typeof (int?))); // -> 1 
WL(StringToType<int>("1"));   // -> 1 
WL(StringToType<int?>("1"));   // error, not compilable 
WL(StringToType<Nullable<int>>("1")); // -> 1 
+0

में लक्ष्य प्रकार है जो मैं कह रहा था कि आप इसे इस तरह प्रतिबिंब के साथ उपयोग नहीं कर सकते हैं, इसके सेटबैसिकप्रॉपर्टीवैल्यू फ्रॉमस्ट्रिंग विधि को इसका उपयोग कैसे किया जाना चाहिए इसके लिए देखें। – weston

+0

आप सही हैं, लेकिन परीक्षण में आप जिस तरह से वर्णन करते हैं उसका उपयोग नहीं कर रहे हैं। एक विधि कोड में और दूसरे परीक्षणों में उपयोगी है। मैं यह नहीं कह रहा हूं कि आपको इसे अपना रास्ता बनाना है, मैं सिर्फ आपके विचार को विस्तारित कर रहा हूं। –

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