2009-08-27 15 views
18

क्या सी # में परम तर्कों को बाहर करना संभव है? मेरे पास है:सी # आउट पैरामीटर कास्टिंग?

Dictionary<string,object> dict; // but I know all values are strings 
string key, value; 

मोटे तौर पर (और मैं स्थिर टाइपिंग अगर नहीं था) मैं क्या करना चाहते हैं:

dict.TryGetValue(key, out value); 

लेकिन यह स्पष्ट रूप से संकलन नहीं होगा क्योंकि यह "से परिवर्तित नहीं कर सकते 'बाहर स्ट्रिंग 'टू ऑब्जेक्ट' '।

वैकल्पिक हल मैं उपयोग कर रहा हूँ है:

object valueAsObject; 
dict.TryGetValue(key, out valueAsObject); 
value = (string) valueAsObject; 

लेकिन वह नहीं बल्कि अजीब लगता है।

क्या किसी भी प्रकार की भाषा सुविधा है जिससे मुझे विधि कॉल में एक पैरामेट डालने की अनुमति मिलती है, तो यह मेरे लिए यह स्विचरू करता है? मैं किसी भी वाक्यविन्यास को समझ नहीं सकता जो मदद करेगा, और मुझे Google के साथ कुछ भी नहीं मिल रहा है।

उत्तर

2

यदि आप जानते हैं कि सभी मान स्ट्रिंग्स Dictionary<string, string> इसके बजाय उपयोग करते हैं। आउट पैरामीटर प्रकार दूसरे सामान्य प्रकार पैरामीटर के प्रकार द्वारा सेट किया गया है। चूंकि आपका वर्तमान में ऑब्जेक्ट है, इसलिए शब्दकोश से पुनर्प्राप्त होने पर यह ऑब्जेक्ट वापस कर देगा। यदि आप इसे स्ट्रिंग में बदलते हैं, तो यह तार वापस कर देगा।

+4

कोई रास्ता नहीं तो मैं एक रूपांतरण विधि के लिए एक प्रतिनिधि में पारित करने के लिए क्षमता जोड़ी मार्क की विधि में रूपांतरण को संभालने के लिए नहीं है शब्दकोश एक इंटरफ़ेस द्वारा प्रदान किया जाता है जिसका मैं उपयोग कर रहा हूं। मुझे पता है कि सभी मूल्य इसके उपयोग के लिए तार हैं, क्योंकि मैं इसे यहां भर रहा हूं। – Ken

0

नहीं, आप नहीं कर सकते। विधि के अंदर कोड सीधे पारित चर को संशोधित कर रहा है, यह चर की सामग्री की एक प्रति पारित नहीं किया गया है।

2

नहीं, इसके आसपास कोई रास्ता नहीं है। आउट पैरामीटर में एक वेरिएबल होना चाहिए जो बिल्कुल मेल खाता हो।

स्ट्रिंग संदर्भ का उपयोग करना सुरक्षित नहीं है, क्योंकि शब्दकोश में तारों की तुलना में अन्य चीजें हो सकती हैं। हालांकि यदि आपके पास तारों का शब्दकोश था और TryGetValue कॉल में ऑब्जेक्ट वैरिएबल का उपयोग करने का प्रयास किया गया, तो यह काम नहीं करेगा, भले ही वह सुरक्षित रहे। परिवर्तनीय प्रकार बिल्कुल मेल खाना है।

18

अगर यह एक बहुत अच्छा विचार है मैं नहीं जानता, लेकिन आप एक सामान्य विस्तार विधि जोड़ सकते हैं:

static bool TryGetTypedValue<TKey, TValue, TActual>(
     this IDictionary<TKey, TValue> data, 
     TKey key, 
     out TActual value) where TActual : TValue 
    { 
     TValue tmp; 
     if (data.TryGetValue(key, out tmp)) 
     { 
      value = (TActual)tmp; 
      return true; 
     } 
     value = default(TActual); 
     return false; 
    } 
    static void Main() 
    { 
     Dictionary<string,object> dict 
      = new Dictionary<string,object>(); 
     dict.Add("abc","def"); 
     string key = "abc", value; 
     dict.TryGetTypedValue(key, out value); 
    } 
+0

यह वाक्य रचनात्मक चीनी का एक दिलचस्प सा है। –

+0

+1 ने इसे किसी शब्दकोश पर कभी नहीं किया है, लेकिन कुछ बहुत ही समान सहायक चरम विधियां हैं। –

+1

एकमात्र चीज जो मैं संभवतः बदलना चाहूंगा वह उस मामले का संचालन होगा जहां मूल्य पाया जाता है लेकिन गलत प्रकार का होता है। फेंकने के बजाय, मैं चाहता हूं कि यह झूठी वापसी करे। फिर फिर, मैं नहीं कर सकता। मुझे इसे खत्म करना होगा, लेकिन यह उल्लेख करने लायक है। –

2

मैं मार्क का विस्तार विधि का इस्तेमाल किया है, लेकिन यह करने के लिए एक सा जोड़ा।

मूल के साथ मेरी समस्या यह थी कि कुछ मामलों में मेरे शब्दकोश में एक int64 होगा जबकि मुझे int int 32 की उम्मीद होगी। अन्य मामलों में शब्दकोश में एक स्ट्रिंग होगी (उदाहरण के लिए "42") जबकि मैं प्राप्त करना चाहता हूं यह एक int के रूप में।

internal static bool TryGetTypedValue<TKey, TValue, TActual>(
     this IDictionary<TKey, TValue> data, 
     TKey key, 
     out TActual value, Func<TValue, TActual> converter = null) where TActual : TValue 
    { 
     TValue tmp; 
     if (data.TryGetValue(key, out tmp)) 
     { 
      if (converter != null) 
      { 
       value = converter(tmp); 
       return true; 
      } 
      if (tmp is TActual) 
      { 
       value = (TActual) tmp; 
       return true; 
      } 
      value = default(TActual); 
      return false; 
     } 
     value = default(TActual); 
     return false; 
    } 

जो तुम इस तरह कॉल कर सकते हैं:

int limit; 
myParameters.TryGetTypedValue("limitValue", out limit, Convert.ToInt32) 
संबंधित मुद्दे