2010-05-05 13 views
5

मैं वर्तमान में एक ऐसे एप्लिकेशन पर काम कर रहा हूं जहां मुझे SQL डेटाबेस से डेटा लोड करने की आवश्यकता है और उसके बाद किसी ऑब्जेक्ट के गुणों में पुनर्प्राप्त मान असाइन करें। मैं प्रतिबिंब का उपयोग कर ऐसा कर रहा हूं क्योंकि संपत्ति के नाम और कॉलम नाम समान हैं। हालांकि, कई गुण कस्टम स्ट्रक्चर प्रकार का उपयोग कर रहे हैं जो मूल रूप से दशमलव प्रकार के लिए मुद्रा रैपर है। मैं अपने struct में एक अंतर्निहित रूपांतरण को परिभाषित किया है:सी # निहित रूपांतरण

public static implicit operator Currency(decimal d) 
{ 
    return new Currency(d); 
} 

यह ठीक काम करता है जब मैं कोड में इसका इस्तेमाल करते हैं। हालांकि, मैं जब इस:

foreach (PropertyInfo p in props) 
{ 
    p.SetValue(this, table.Rows[0][p.Name], null); 
} 

यह एक ArgumentException करते हुए कहा कि यह System.Decimal से मुद्रा को परिवर्तित नहीं कर सकते फेंकता है। मैं उलझन में हूं क्योंकि यह किसी अन्य परिस्थिति में ठीक काम करता है।

उत्तर

3

मुझे लगता है कि आप पहली बार Unbox करने के लिए एक decimal रूप table.Rows[0][p.Name] में मूल्य की जरूरत है।

दूसरे शब्दों में:

foreach (PropertyInfo p in props) 
{ 
    if (p.PropertyType == typeof(Currency)) 
    { 
     Currency c = (decimal)table.Rows[0][p.Name]; 
     p.SetValue(this, c, null); 
    } 
    else 
    { 
     p.SetValue(this, table.Rows[0][p.Name], null); 
    } 
} 

यह एक मुद्दा मैं एक या दो बार पहले देखा है है, इसलिए मैं वास्तव में write a blog post about it का फैसला किया। कोई भी थोड़ा और स्पष्टीकरण की तलाश में है, इसे पढ़ने के लिए स्वतंत्र महसूस करें।

+0

इस उत्कृष्ट काम किया! धन्यवाद! –

0

जबकि मैं तुम्हारी समस्या का जवाब दे नहीं कर रहा हूँ, मैं इस स्थिति के इस प्रकार में लगता है कि यह इकाई की रूपरेखा या NHibernate जो आपके डोमेन वस्तुओं में अपने टेबल नक्शा और के लिए सभी रूपांतरणों संभाल लेंगे तरह एक ORM फ्रेमवर्क का उपयोग करने के अधिक उचित होगा आप। एक डोमेन ऑब्जेक्ट में भरने वाले फ़ील्ड को समझने के लिए प्रतिबिंब जैसे कुछ का उपयोग करना यह करने का एक धीमा तरीका है।

+1

आम तौर पर मैं इसके बारे में बहुत चिंतित होना चाहते हैं, लेकिन यह वास्तव में मैं क्या इकट्ठा कर सकते हैं से प्रभावित नहीं होते। यह डेटा का अपेक्षाकृत छोटा सेट (56 कॉलम/गुण) है, इसलिए अतिरिक्त ओवरहेड एक बड़ा मुद्दा नहीं है। यद्यपि मेरे द्वारा सुझाव की सराहना की जाती है। –

2

मुझे लगता है कि table, अपने कोड में टाइप DataTable की है, इसलिए पहले इंडेक्सर एक DataRow देता है, और दूसरा एक एक object देता है। फिर PropertyInfo.SetValue दूसरे तर्क के रूप में object भी लेता है। इस कोड में किसी भी स्थान पर कोड कोड में होता है, इसलिए अधिभारित रूपांतरण ऑपरेटर लागू नहीं होता है।

सामान्य शब्दों में, यह जब स्थिर प्रकार जाना जाता है (पल के लिए सी # 4.0 में dynamic के बारे में भूल जाते हैं) केवल लागू किया जाता है। मुक्केबाजी और अनबॉक्सिंग चीजें जब यह लागू नहीं होती है। इस मामले में, DataRow पर सूचकांक मान बॉक्स करता है, और PropertyInfo.SetValue इसे किसी भिन्न प्रकार से अनबॉक्स करने का प्रयास करता है - और विफल रहता है।

10

दुर्भाग्यवश, इन उपयोगकर्ता परिभाषित रूपांतरण ऑपरेटरों को रनटाइम द्वारा उपयोग नहीं किया जाता है; वे केवल संकलन समय पर संकलक द्वारा उपयोग किया जाता है। तो अगर आप एक जोरदार टाइप decimal लेने के लिए और करने के लिए एक जोरदार टाइप Currency असाइन करें, संकलक अपने रूपांतरण ऑपरेटर के लिए एक कॉल से जोड़ दिया जाएगा और हर कोई खुश है। हालांकि, जब तुम SetValue फोन के रूप में आप यहाँ क्या कर रहे हैं, क्रम में आप इसे उचित प्रकार का एक मूल्य देने के लिए अपेक्षा करता है; रनटाइम को यह नहीं पता कि यह रूपांतरण ऑपरेटर मौजूद है, और इसे कभी भी कॉल नहीं करेगा।

+2

बिल्कुल। लागू रूपांतरण एक्सटेंशन विधियों और डिफ़ॉल्ट पैरामीटर के समान हैं - कुछ संकलक करता है। – TomTom

+0

आह, मैं देखता हूं। मैं अंतर्दृष्टि की सराहना करता हूं, मुझे ऐसा करने का बेहतर तरीका पता लगाने में सक्षम होना चाहिए। धन्यवाद :) –

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