यह अजीब आप इसे का उल्लेख करना चाहिए, क्योंकि मैं कुछ के साथ चारों ओर खिलवाड़ किया गया था सिर्फ इस दूसरे दिन की तरह है:
using System;
using System.Reflection;
static class Example
{
public static Tuple<Boolean, T?> TryParse<T>(this String candidate)
where T : struct
{
T? value = null;
Boolean success = false;
var parser = ParsingBinder<T>.GetParser();
try
{
value = parser(candidate);
success = true;
}
catch (FormatException) { }
return new Tuple<Boolean,T?>(success, value);
}
}
static class ParsingBinder<T>
{
static Func<String, T> parser;
public static Func<String, T> GetParser()
{
if (parser == null)
parser = getParser();
return parser;
}
static Func<String, T> getParser()
{
MethodInfo methodInfo
= typeof(T).GetMethod(
"Parse", new [] { typeof(String) });
if (methodInfo == null)
throw new Exception(
"Unable to retrieve a \"Parse\" method for type.");
return (Func<String, T>)Delegate
.CreateDelegate(typeof(Func<String, T>), methodInfo);
}
}
यह एक समान दृष्टिकोण है, लेकिन एक बेहतर TryParse
विधि है कि एक Tuple<Boolean, T?>
रिटर्न के रूप में विचार (इसके लिए .NET 4 की आवश्यकता है)। टुपल की पहली संपत्ति एक बूलियन वैल्यू है जो पार्सिंग प्रयास की सफलता या विफलता का संकेत देती है और दूसरी संपत्ति जेनेरिक टाइप तर्क के लिए टाइप की गई एक शून्य मूल्य है जो null
होगी यदि पार्सिंग विफल हो जाती है और यदि पार्सिंग सफल होती है तो मान।
यह प्रतिबिंब का उपयोग कर सामान्य प्रकार तर्क से एक स्थिर Parse(String)
विधि पुनः प्राप्त करने के द्वारा काम करता है और स्ट्रिंग है जो में मैं तुम्हें इस तरह सामान ऐसा करने की अनुमति के लिए एक विस्तार पद्धति के रूप में इसे बनाया पारित हो जाता है के लिए है कि विधि का आह्वान:।
var intValue = "1234".TryParse<Int32>();
var doubleValue = "1234".TryParse<Double>();
दुर्भाग्य से इस enums
पर काम नहीं करेगा क्योंकि वे तो आप एक enum
पार्स करने के लिए इस एक्सटेंशन का उपयोग नहीं कर सकता है पार्स विधि के लिए एक ही हस्ताक्षर की जरूरत नहीं है, लेकिन यह इस पर निर्भर हैक करने के लिए कठिन नहीं होगा enums के लिए एक विशेष मामला बनाओ।
इस दृष्टिकोण के बारे में अच्छी चीजों में से एक यह है कि प्रतिबिंब के माध्यम से Parse
विधि को पुनर्प्राप्त करने की लागत केवल पहले उपयोग पर होती है क्योंकि सभी बाद के उपयोगों के लिए एक स्थिर प्रतिनिधि बनाया जाता है।
एक और बात - केवल एक चीज है कि इस दृष्टिकोण के बारे में भद्दा है कि वहाँ कोई भाषा एक्सटेंशन या वाक्यात्मक चीनी है कि इस के साथ काम करने के लिए आसान हो जाएगा है। मैं इस कोड के साथ प्राप्त करने की उम्मीद कर रहा था कम बीसीएल में मौजूद मानक TryParse
विधियों का उपयोग करने का गुंजाइश तरीका था।
मैं व्यक्तिगत रूप से नहीं बल्कि बदसूरत इस पैटर्न को खोजने:
Int32 value;
if (Int32.TryParse(someString, out value))
// do something with value
मुख्य रूप से, क्योंकि यह एक चर घोषणा समय से आगे और एक out
पैरामीटर के उपयोग की आवश्यकता है। ऊपर मेरे दृष्टिकोण वास्तव में है कि ज्यादा बेहतर नहीं है:
var result = someString.TryParse<Int32>();
if (result.Item1)
// do something with result.Item2
क्या वास्तव में एक सी # भाषा विस्तार है कि एक Tuple<Boolean, T?>
के साथ काम करने कि हम आसानी से इस प्रकार के साथ काम करने की अनुमति होगी बनाया गया था देखने के लिए किया जाएगा शांत होगा, लेकिन मुझे लगता है कि मैं इस बारे में और अधिक महसूस कर रहा हूं कि यह वास्तव में संभव नहीं लगता है। बस करो: प्रश्न चिह्न का उपयोग करने का
वास्तव में इस मान लिया जाये, काम करता है + 1: पी –
'की TryParse' विफलता पर एक अपवाद फेंक नहीं है अस्तित्व के लिए प्राथमिक उद्देश्य को ध्यान में रखते, अपने" बेहतर दृष्टिकोण "अपने अस्तित्व के उद्देश्य पूर्ववत है: http: //www.codinghorror.com/blog/archives/000358.html –
@ 280z28 - पर्याप्त मेला लेकिन अपवाद जो मैं फेंकता हूं वह अलग है। यह अपवाद तब फेंक दिया जाता है जब आप उस प्रकार को पार्स करने का प्रयास करते हैं जिसमें 'TryParse (स्ट्रिंग)' विधि नहीं होती है जो कभी भी तब नहीं होती जब आप सामान्य 'TryParse' विधि को कॉल करते हैं। यह अपवाद निस्संदेह डेवलपर द्वारा परीक्षण में पाया जाएगा और रनटाइम पर नहीं होगा, इसलिए यह बिल्कुल वही नहीं है जैसे अपवाद को पार्सिंग विफलता से मुखौटा किया जाएगा। –