यह कैसे जांचा जाए कि वेरिएबल का प्रकार मैच वेरिएबल में किस प्रकार संग्रहित है


96
User u = new User();
Type t = typeof(User);

u is User -> returns true

u is t -> compilation error

यदि कोई चर इस प्रकार से है, तो मैं कैसे परीक्षण करूं?

जवाबों:


194

अन्य उत्तरों में सभी महत्वपूर्ण चूक हैं।

isऑपरेटर करता नहीं की जाँच करता है, तो संकार्य के क्रम प्रकार है वास्तव में दिए गए प्रकार; इसके बजाय, यह देखने के लिए जांचता है कि रनटाइम प्रकार दिए गए प्रकार के साथ संगत है या नहीं :

class Animal {}
class Tiger : Animal {}
...
object x = new Tiger();
bool b1 = x is Tiger; // true
bool b2 = x is Animal; // true also! Every tiger is an animal.

लेकिन प्रकार के लिए जाँच पहचान के लिए प्रतिबिंब के चेक के साथ पहचान , के लिए नहीं अनुकूलता

bool b5 = x.GetType() == typeof(Tiger); // true
bool b6 = x.GetType() == typeof(Animal); // false! even though x is an animal

or with the type variable
bool b7 = t == typeof(Tiger); // true
bool b8 = t == typeof(Animal); // false! even though x is an 

अगर वह नहीं है जो आप चाहते हैं, तो आप शायद IsAssignableFrom चाहते हैं:

bool b9 = typeof(Tiger).IsAssignableFrom(x.GetType()); // true
bool b10 = typeof(Animal).IsAssignableFrom(x.GetType()); // true! A variable of type Animal may be assigned a Tiger.

or with the type variable
bool b11 = t.IsAssignableFrom(x.GetType()); // true
bool b12 = t.IsAssignableFrom(x.GetType()); // true! A 

4
जबकि यहां दिखाया गया अंतिम तरीका काम करता है, यह अनावश्यक रूप से क्रिया है। typeof(Animal).IsInstanceOfType(x)तुलना में छोटा और अधिक सीधा है typeof(Animal).IsAssignableFrom(x.GetType());(और यदि आप बाद वाले का उपयोग करते हैं तो Resharper पूर्व का उपयोग करने का सुझाव देगा)।
मार्क अमेरी

क्लैरिएशन: मूल प्रश्न का उत्तर देने के tलिए , विकल्प typeof(Animal)। तो मार्क का बेहतर रूप बन जाता है t.IsInstanceOfType(x)
टूलमेकरसैट

13

GetType()हर एक फ्रेमवर्क प्रकार पर मौजूद है, क्योंकि यह आधार objectप्रकार पर परिभाषित किया गया है । इसलिए, स्वयं प्रकार की परवाह किए बिना, आप इसका उपयोग अंतर्निहित वापस करने के लिए कर सकते हैंType

तो, आपको बस इतना करना चाहिए:

u.GetType() == t

1
वास्तव में एरिक का जवाब सहायक और सभी है, लेकिन मूल प्रश्न में वर्णित "यू टी है" तरीके से अज्ञात प्रकार के साथ परीक्षण करने के वास्तविक प्रश्न का उत्तर नहीं देता है, और आपका करता है।
डैनियल

@ डैनियल - बिल्कुल नहीं। यदि आप t के उपवर्गों को बाहर करना चाहते हैं तो डेव का उत्तर केवल सही है। एरिक का जवाब ज्यादातर बताता है कि क्या करना है; यह केवल "टी" कहां रखा गया है इसका स्पष्टीकरण गायब है। मैं वहाँ एक टिप्पणी जोड़ दूँगा।
टूलमेकर

10

आपको यह देखने की ज़रूरत है कि क्या आपकी आवृत्ति का प्रकार वर्ग के प्रकार के बराबर है। आप जिस GetType()विधि का उपयोग करते हैं उसका प्रकार प्राप्त करने के लिए :

 u.GetType().Equals(t);

या

 u.GetType.Equals(typeof(User));

करना चाहिए। यदि आप चाहें तो अपनी तुलना करने के लिए स्पष्ट रूप से आप '==' का उपयोग कर सकते हैं।


+1 लेकिन दूसरी पसंद को प्राथमिकता दें। u.GetType.Equals(typeof(User));
उमर

एक कारण यह == का उपयोग करने की तुलना में कम सुरक्षित है कि अगर गेट टाइप () किसी तरह से अशक्त हो जाता है - तो यह फेंक देगा।
डेव बिष्ट

1
@Fuex, मुझे हाँ, मुझे लगता है कि अगर यह टाइपऑफ़ इनलाइन है तो कोड को पढ़ना आसान बनाता है, यही कारण है कि मैंने इसे इस तरह पोस्ट किया है, भले ही ओपी उदाहरण में उसके पास पहले से ही एक चर है tजिसमें टाइप शामिल है।
सैम होल्डर

@DaveBish अगर GetType वापस लौट आया है, तो मुझे चिंता होगी कि बहुत सारी चीजें फेंकना शुरू हो जाएंगी ... लेकिन इशारा किया, आप बिल्कुल सही हैं
सैम होल्डर

@SamHolder हाँ - केवल यही स्थिति होगी, अगर किसी ने आधार प्रकार को ओवररोड किया, और कार्यान्वयन को किसी तरह खराब कर दिया। यह निश्चित रूप से अजीब होगा।
डेव बिष्ट

4

यह जांचने के लिए कि क्या कोई वस्तु लेखन के बजाय किसी दिए गए प्रकार चर के साथ संगत है

u is t

आपको लिखना चाहिए

typeof(t).IsInstanceOfType(u)

1
'U t t' सिंटैक्स बनाम अधिक वर्बोज़ सिंटैक्स का क्या लाभ है?
काइल हमफेल्ड

@ केलीहुमफ़ेल्ड यदि आपके पास टाइप फू था; वस्तु ए; आप "A is foo" नहीं लिख सकते, लेकिन आप foo.isInstanceOfType (A)
तैमूर नूरियासोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.