परीक्षण करना यदि कोई ऑब्जेक्ट सी #


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

यह शायद प्रतिबिंब का उपयोग करने से बॉक्स किए गए मूल्य का उपयोग करके बेहतर प्रदर्शन करेगा। 23 sep. 082008-09-23 19:33:30

  0

मुझे यकीन नहीं है कि आपका क्या मतलब है? इससे मूल्य निकालने के लिए आप केवल एक KeyValuePair <TKey,TValue> बॉक्स नहीं कर सकते हैं। 23 sep. 082008-09-23 19:38:02

  0

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

  0

@Guvante वास्तव में बदल दिया है, आप सामान्य प्रकार के साथ 'typeof' का उपयोग करते समय टाइप पैरामीटर को छोड़ सकते हैं। यहां देखें: http://msdn.microsoft.com/en-us/library/b8ytshk6.aspx 23 oct. 132013-10-23 13:28:00

  0

@TimGoodman: यह अजीब बात है, मैंने उस वाक्यविन्यास की कोशिश की और संकलन त्रुटि प्राप्त की, हटा दिया। 23 oct. 132013-10-23 23:55:52


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 <TKey,TValue> पता वास्तव में IDictionary इंटरफ़ेस को लागू नहीं करता है ? तो यह सामान्य शब्दकोशों के लिए काम नहीं करेगा। Http://msdn.microsoft.com/en-us/library/s4ys34ea.aspx 23 sep. 082008-09-23 19:32:36

  0

पर भी देखें, भले ही यह एक शब्दकोश <TKey,TValue> था जो IDictionary को लागू करता है, तो यह IENumerable <KeyValuePair <TKey,TValue>> लागू करता है, इसलिए मैं उम्मीद करता हूं असफल होने के लिए शब्दकोश एंट्री के मामले। 23 sep. 082008-09-23 19:39:05

  0

बेशक मेरा मतलब है "उपरोक्त शब्दकोश एंट्री"। 23 sep. 082008-09-23 19:44:31

  0

शब्दकोश एंट्री कास्टिंग विफल हो जाता है। अभी तक समाधान का पता नहीं लगा है। 23 sep. 082008-09-23 19:50:26

+1

ग्रेग बीच को ठीक करने के लिए, मैंने अभी तक शब्दकोश खींच लिया <>, और यह वास्तव में IDictionary को लागू करता है, भले ही IDictionary <> नहीं। भूल गए कि यद्यपि शब्दकोश प्राप्त करने के लिए एक इंडेक्सिंग विधि का उपयोग करने से काम करना होगा, मैं इसे चयनित इटैम नहीं डाल सकता। अगर मुझे गैर प्रतिबिंब समाधान मिल जाए तो ठीक हो जाएगा। 24 sep. 082008-09-24 00:58:21


0

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

+1

अपनी शब्दावली से सावधान रहें, जेनेरिक के रूप में गैर-जेनेरिक संस्करणों का जिक्र करना शायद कुछ लोगों को भ्रमित कर रहा है (मुझे पता है कि मुझे हमेशा खुद को सही करना होगा: पी) 23 sep. 082008-09-23 19:26:37


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