निम्नलिखित सरल कोड की कल्पना कीजिए:सामान्य प्रकार के मूल्य को बॉक्सिंग के बिना डबल करने के लिए कैसे करें?
public void F<T>(IList<T> values) where T : struct
{
foreach (T value in values)
{
double result;
if (TryConvertToDouble((object)value, out result))
{
ConsumeValue(result);
}
}
}
public void ConsumeValue(double value)
{
}
ऊपर कोड आपत्ति उठाने का है, जो पाश में मुक्केबाजी में परिणाम कास्टिंग है के साथ समस्या।
क्या समान कार्यक्षमता प्राप्त करने का कोई तरीका है, यानी फॉरेच लूप में मुक्केबाजी का उपयोग किए बिना सभी मूल्यों के साथ उपभोग करें। नोट, कि एफ एक सामान्य विधि होना चाहिए।
मैं एक महंगी तैयारी कोड के साथ रह सकता हूं जब तक कि इसे केवल एक बार लूप के बाहर निष्पादित किया जाता है। उदाहरण के लिए, यदि एक फैंसी गतिशील विधि को उत्सर्जित करने की आवश्यकता है, तो यह ठीक है अगर एक बार किया जाता है।
संपादित
टी कुछ संख्यात्मक प्रकार या bool के होने की गारंटी है।
प्रेरणा। मेटा डेटा संचालित एप्लिकेशन की कल्पना करें, जहां एक एजेंट डेटा स्ट्रीम की रिपोर्ट करता है, जहां डेटा आइटम प्रकार डेटा स्ट्रीम मेटा डेटा के आधार पर गतिशील रूप से उत्सर्जित होता है। कल्पना कीजिए कि सामान्यीकृत इंजन है, जो कुछ एल्गोरिदम के अनुसार संख्यात्मक डेटा धाराओं को सामान्य करना जानता है। इनकमिंग न्यूमेरिक डेटा स्ट्रीम का प्रकार केवल रन टाइम पर जाना जाता है और इसे उस डेटा प्रकार की सामान्य विधि के लिए निर्देशित किया जा सकता है। हालांकि, सामान्य उत्पादक युगल की अपेक्षा करता है और युगल पैदा करता है। यह एक बहुत ही उच्च स्तर का वर्णन है, कृपया इसमें शामिल न हों।
EDIT2
कलाकारों को दोगुना करने के संबंध में। असल में हम निम्न हस्ताक्षर के साथ दोगुना करने के लिए कन्वर्ट करने के लिए एक विधि है:
bool TryConvertToDouble(object value, out double result);
मैं पहली जगह में उदाहरण में इसका इस्तेमाल किया जाना चाहिए था, लेकिन मैं अंतरिक्ष और लिखित कुछ है कि काम करने के लिए नहीं जा रहा है को बचाने के लिए करना चाहता था। इसे अभी तय करें। ध्यान देने के लिए धन्यवाद।
EDIT3
दोस्तों, वर्तमान कार्यान्वयन मूल्यों बॉक्स करता है। और यहां तक कि यदि मेरे पास इसके प्रदर्शन प्रदर्शन के लिए प्रोफाइलर का निर्णय नहीं है (यदि कोई है), फिर भी मुझे यह जानना दिलचस्प है कि मुक्केबाजी के बिना कोई समाधान है (और स्ट्रिंग में कनवर्ट किए बिना)। मुझे इसे पूरी तरह अकादमिक हित कहते हैं। यह वास्तव में मुझे रूचि देता है, क्योंकि इस तरह की चीजें टेम्पलेट्स के साथ सी ++ में तुच्छ होती हैं, लेकिन, ज़ाहिर है, मैं अभी भी एक और बेवकूफ और व्यर्थ तर्क नहीं कर रहा हूं जो बेहतर है .NET जेनेरिक या सी ++ टेम्पलेट्स। कृपया, इस अंतिम वाक्य को अनदेखा करें।
EDIT4
https://stackoverflow.com/users/267/lasse-v-karlsen जो उत्तर प्रदान करने के लिए धन्यवाद। वास्तव में, मैं अपने कोड नमूना का इस्तेमाल किया है इस तरह एक साधारण वर्ग में लिखने के लिए:
public static class Utils<T>
{
private static class ToDoubleConverterHolder
{
internal static Func<T, double> Value = EmitConverter();
private static Func<T, double> EmitConverter()
{
ThrowIfNotConvertableToDouble(typeof(T));
var method = new DynamicMethod(string.Empty, typeof(double), TypeArray<T>.Value);
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
if (typeof(T) != typeof(double))
{
il.Emit(OpCodes.Conv_R8);
}
il.Emit(OpCodes.Ret);
return (Func<T, double>)method.CreateDelegate(typeof(Func<T, double>));
}
}
public static double ConvertToDouble(T value)
{
return ToDoubleConverterHolder.Value(value);
}
}
कहाँ:
- ThrowIfNotConvertableToDouble (प्रकार) एक सरल विधि यकीन है कि दिए गए प्रकार दोगुना करने के लिए परिवर्तित किया जा सकता बनाता है , यानी कुछ संख्यात्मक प्रकार या बूल।
- TypeArray एक सहायक वर्ग
new[]{ typeof(T) }
Utils.ConvertToDouble विधि किसी भी सांख्यिक मान लिए सबसे कारगर तरीका में दोगुना करने के लिए, इस सवाल का जवाब द्वारा दिखाए गए धर्मान्तरित उत्पादन होता है।
यह एक आकर्षण की तरह काम करता है - धन्यवाद आदमी।
समस्या से ऊपर के साथ है कि यह ज्यादा मतलब नहीं है भी है। एक बाधा के साथ एक सामान्य विधि का उपयोग क्यों करें, और फिर इसे दो बार तक डाला जाए? क्या आप स्पष्ट रूप से समझा सकते हैं कि आप क्या हासिल करने की कोशिश कर रहे हैं? –
यह सिर्फ मेरे लिए अजीब लगता है। आप किसी ऑब्जेक्ट के लिए जेनेरिक स्ट्रक्चर कास्टिंग क्यों कर रहे हैं और फिर डबल पर? क्या इस उदाहरण के साथ कुछ गलत है? क्या हमें और संदर्भ की आवश्यकता है? यह कोड जगह से बाहर लगता है, मुझे नहीं पता कि इसका उत्तर कैसे दिया जाए ... –
मैंने प्रश्न अपडेट किया है। – mark