2008-09-23 14 views
14

में एक शब्दकोश है तो परीक्षण करने का कोई तरीका है कि कोई ऑब्जेक्ट एक शब्दकोश है या नहीं?परीक्षण करना यदि कोई ऑब्जेक्ट सी #

एक विधि में मैं एक सूची बॉक्स में किसी चयनित आइटम से मूल्य प्राप्त करने का प्रयास कर रहा हूं। कुछ परिस्थितियों में, सूची बॉक्स एक शब्दकोश के लिए बाध्य हो सकता है, लेकिन यह संकलन समय पर ज्ञात नहीं है।

if (listBox.ItemsSource is Dictionary<??>) 
{ 
    KeyValuePair<??> pair = (KeyValuePair<??>)listBox.SelectedItem; 
    object value = pair.Value; 
} 

वहाँ प्रतिबिंब का उपयोग क्रम में गतिशील रूप से यह करने के लिए एक रास्ता है:

मैं इस के समान कुछ करना चाहते हैं? मुझे पता है कि जेनेरिक प्रकारों के साथ प्रतिबिंब का उपयोग करना और कुंजी/मान पैरामीटर निर्धारित करना संभव है, लेकिन मुझे यकीन नहीं है कि उन मानों को पुनर्प्राप्त करने के बाद बाकी करने का कोई तरीका है या नहीं।

उत्तर

10

यह निम्न की तरह कुछ होना चाहिए। मैंने इसे उत्तर बॉक्स में लिखा था, इसलिए सिंटैक्स बिल्कुल सही नहीं हो सकता है, लेकिन मैंने इसे विकी संपादन योग्य बना दिया है ताकि कोई भी ठीक हो सके।

if (listBox.ItemsSource.IsGenericType && 
    typeof(IDictionary<,>).IsAssignableFrom(listBox.ItemsSource.GetGenericTypeDefinition())) 
{ 
    var method = typeof(KeyValuePair<,>).GetProperty("Value").GetGetMethod(); 
    var item = method.Invoke(listBox.SelectedItem, null); 
} 
+0

यह शायद प्रतिबिंब का उपयोग करने से बॉक्स किए गए मूल्य का उपयोग करके बेहतर प्रदर्शन करेगा। –

+0

मुझे यकीन नहीं है कि आपका क्या मतलब है? इससे मूल्य निकालने के लिए आप केवल एक KeyValuePair बॉक्स नहीं कर सकते हैं। –

+0

आपका समाधान काम किया। मैंने आगे बढ़ने के लिए अगर कथन बदल दिया है और बस "IDictionary" का परीक्षण करें (आपके टाइप का हिस्सा कुछ कारणों से काम नहीं करता है)। मैंने "टाइपबॉक्स (KeyValuePair <,>)" को "सूची बॉक्स" चयनित " –

13

यह देखने के लिए जांचें कि क्या यह IDictionary लागू करता है।

सिस्टम.कोलेक्शन .IDictionary की परिभाषा को देखने के लिए जो आपको देता है उसे देखें।

if (listBox.ItemsSource is IDictionary) 
{ 
    DictionaryEntry pair = (DictionaryEntry)listBox.SelectedItem; 
    object value = pair.Value; 
} 

संपादित करें: वैकल्पिक जब मुझे एहसास हुआ KeyValuePair के DictionaryEntry

if (listBox.DataSource is IDictionary) 
{ 
    listBox.ValueMember = "Value"; 
    object value = listBox.SelectedValue; 
    listBox.ValueMember = ""; //If you need it to generally be empty. 
} 

यह समाधान प्रतिबिंब का उपयोग करता है करने के लिए castable नहीं हैं, लेकिन इस मामले में आप घुरघुराना काम करने के लिए नहीं है, Listbox यह आपके लिए करता है। इसके अलावा यदि आपके पास आमतौर पर डेटा स्रोतों के रूप में शब्दकोश होते हैं तो आप हर समय ValueMember को रीसेट करने से बचने में सक्षम हो सकते हैं।

+3

उम, आप IDictionary पता वास्तव में IDictionary इंटरफ़ेस को लागू नहीं करता है ? तो यह सामान्य शब्दकोशों के लिए काम नहीं करेगा। Http://msdn.microsoft.com/en-us/library/s4ys34ea.aspx –

+0

पर भी देखें, भले ही यह एक शब्दकोश था जो IDictionary को लागू करता है, तो यह IENumerable > लागू करता है, इसलिए मैं उम्मीद करता हूं असफल होने के लिए शब्दकोश एंट्री के मामले। –

+0

बेशक मेरा मतलब है "उपरोक्त शब्दकोश एंट्री"। –

0

आप थोड़ा और सामान्य हो सकते हैं और इसके बजाय पूछ सकते हैं कि यह IDictionary लागू करता है। फिर KeyValue संग्रह contina सादा Objects होगा।

+1

अपनी शब्दावली से सावधान रहें, जेनेरिक के रूप में गैर-जेनेरिक संस्करणों का जिक्र करना शायद कुछ लोगों को भ्रमित कर रहा है (मुझे पता है कि मुझे हमेशा खुद को सही करना होगा: पी) – Guvante

1

आप यह देखने के लिए जांच सकते हैं कि यह IDictionary लागू करता है या नहीं। आपको DictionaryEntry कक्षा का उपयोग करके गणना करना होगा।

0

मेरा मानना ​​है कि एक चेतावनी है।

जब आप परीक्षण कर रहे हैं कि कोई ऑब्जेक्ट 'यह' है या नहीं, तो आप टाइप सिस्टम को पुन: कार्यान्वित कर रहे हैं। पहला 'ए' ए अक्सर एक दूसरे के बाद तेजी से पीछा किया जाता है, और जल्द ही आपका कोड टाइप प्रकार से भरा होता है, जिसे टाइप सिस्टम द्वारा बहुत अच्छी तरह से संभाला जाना चाहिए - कम से कम ऑब्जेक्ट उन्मुख डिज़ाइन में।

बेशक, मुझे प्रश्न के संदर्भ के बारे में कुछ नहीं पता है। मैं हमारे अपने codebase कि स्ट्रिंग रूपांतरण करने के लिए 50 विभिन्न वस्तु संभालती में एक 2000 लाइन फ़ाइल पता है ... :(

0
if(typeof(IDictionary).IsAssignableFrom(listBox.ItemsSource.GetType())) 
{ 

} 
3

मैं जानता हूँ कि इस सवाल का कई साल पहले पूछा गया था, लेकिन यह अभी भी सार्वजनिक रूप से दिखाई देता है।

कुछ इस विषय में यहाँ प्रस्तावित उदाहरण थे और में यह एक:
Determine if type is dictionary [duplicate]

लेकिन वहाँ कुछ बेमेल हैं, इसलिए मैं अपने समाधान साझा करना चाहते हैं

लघु जवाब:

var dictionaryInterfaces = new[] 
{ 
    typeof(IDictionary<,>), 
    typeof(IDictionary), 
    typeof(IReadOnlyDictionary<,>), 
}; 

var dictionaries = collectionOfAnyTypeObjects 
    .Where(d => d.GetType().GetInterfaces() 
     .Any(t=> dictionaryInterfaces 
      .Any(i=> i == t || t.IsGenericType && i == t.GetGenericTypeDefinition()))) 

लंबा उत्तर:
मेरा मानना ​​है कि यह कारण है कि लोगों को गलती करते हैं:

//notice the difference between IDictionary (interface) and Dictionary (class) 
typeof(IDictionary<,>).IsAssignableFrom(typeof(IDictionary<,>)) // true 
typeof(IDictionary<int, int>).IsAssignableFrom(typeof(IDictionary<int, int>)); // true 

typeof(IDictionary<int, int>).IsAssignableFrom(typeof(Dictionary<int, int>)); // true 
typeof(IDictionary<,>).IsAssignableFrom(typeof(Dictionary<,>)); // false!! in contrast with above line this is little bit unintuitive 

तो कहते हैं कि हम इस प्रकार की है:

public class CustomReadOnlyDictionary : IReadOnlyDictionary<string, MyClass> 
public class CustomGenericDictionary : IDictionary<string, MyClass> 
public class CustomDictionary : IDictionary 

और इन उदाहरणों:

var dictionaries = new object[] 
{ 
    new Dictionary<string, MyClass>(), 
    new ReadOnlyDictionary<string, MyClass>(new Dictionary<string, MyClass>()), 
    new CustomReadOnlyDictionary(), 
    new CustomDictionary(), 
    new CustomGenericDictionary() 
}; 

इसलिए यदि हम का उपयोग करेगा IsAssignableFrom() विधि:

var dictionaries2 = dictionaries.Where(d => 
    { 
     var type = d.GetType(); 
     return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type.GetGenericTypeDefinition()); 
    }); // count == 0!! 

हम किसी भी उदाहरण नहीं मिलेगा

तो सबसे अच्छा तरीका है कि उनमें से कोई शब्दकोश इंटरफेस है सभी इंटरफ़ेस मिलता है और जांच करने के लिए है:

var dictionaryInterfaces = new[] 
{ 
    typeof(IDictionary<,>), 
    typeof(IDictionary), 
    typeof(IReadOnlyDictionary<,>), 
}; 

var dictionaries2 = dictionaries 
    .Where(d => d.GetType().GetInterfaces() 
     .Any(t=> dictionaryInterfaces 
      .Any(i=> i == t || t.IsGenericType && i == t.GetGenericTypeDefinition()))) // count == 5 
संबंधित मुद्दे