2010-09-04 12 views
9

क्या रनटाइम पर जांचना संभव है कि दिया गया प्रकार कस्टम डेटा प्रकार या .NET के आदिम डेटा प्रकारों में से एक है?.NET में प्रतिबिंब का उपयोग करके असेंबली में एक प्रकार कस्टम प्रकार या आदिम प्रकार निर्धारित करने और जांचने के लिए कैसे करें?

मैंने उपयोगकर्ता परिभाषित प्रकारों को असेंबली में परिभाषित किया है और उन सभी प्रकार कुछ structs हैं। मुझे उन परिभाषित प्रकारों के उपयोगकर्ता परिभाषित प्रकारों के तरीकों को कॉल करने की आवश्यकता है जो वे structs हैं। इसलिए प्रतिबिंब का उपयोग करके रनटाइम पर उन फ़ंक्शन को कॉल करने से पहले डेटा को भरने की आवश्यकता है।

अब किसी भी विधि प्रतिबिंब में उपलब्ध है जिसके द्वारा हम ट्रैक कर सकते हैं कि दिए गए डेटा प्रकार कस्टम या आदिम डेटा प्रकार है। मुझे IsClass विशेषता के बारे में पता है, लेकिन मेरे लक्षित उपयोगकर्ता परिभाषित डेटा प्रकार कक्षाएं नहीं हैं, ये लोग स्ट्राइक हैं।

+0

'कस्टम' और 'आदिम' में .NET -' string' में उपलब्ध सभी प्रकार के प्रकार शामिल नहीं हैं, उदाहरण के लिए, श्रेणियों में से किसी एक में फिट नहीं है। 'बीसीएल द्वारा प्रदान की गई' या 'अन्यत्र प्रदान की गई' या 'आदिम'/'आदिम 'जैसी कोई प्रभाग एक पूर्ण उपखंड है। –

उत्तर

1
+0

उल्लेखनीय है (मेरे उत्तर के अनुसार) कि 'IsPrimitive' स्ट्रिंग के लिए झूठा रिटर्न देता है, जो कि आदिम = " – Rob

+0

" की आपकी "परिभाषा" के आधार पर थोड़ा गलत है, मेरे आश्चर्य के लिए, सीएलआई मानक (Ecma-335) उपयोग करता है इसे परिभाषित किए बिना "आदिम प्रकार" शब्द। सी # भाषा विनिर्देश (एक्मा -334), हालांकि, उन्हें "सरल प्रकार" कहते हैं और शब्द को 'दशमलव', 'बूल' और' char' समेत सभी संख्यात्मक मान प्रकारों को शामिल करने के लिए परिभाषित करता है, लेकिन संदर्भ प्रकारों में से कोई भी नहीं (इसलिए नहीं 'स्ट्रिंग' और कोई 'ऑब्जेक्ट') नहीं। – Timwi

0

एक बहुत ही सरल, determing एक प्रकार बीसीएल/CLR द्वारा प्रदान की गई है कि क्या के अल्पविकसित तरीका है:

ध्यान रखें कि Type.IsPrimitive का उपयोग कर System.String के लिए झूठी वापस आ जाएगी में
var type = typeof(int); 
var isSystemType = type.Assembly.FullName.StartsWith("mscorlib"); 

भालू, इसलिए यह इस बात पर निर्भर करता है कि आप "आदिम" की परिभाषा का उपयोग कर रहे हैं कि यह उपयुक्त है या नहीं।

+0

विचार ठीक है, लेकिन यह 'टाइपऑफ (int) करने के लिए बेहतर नहीं होगा। एस्परप्लेस। एक्वाल्स (उम्मीदवार टाइप); या कुछ? क्या होगा अगर कोई 'mscorlibextensions' बनाता है? – Ani

+0

@ एनी - मैंने कहा था कि यह बहुत ही सरल और प्राथमिक था! =) – Rob

+0

जब मैं अपनी खुद की असेंबली को परिभाषित करता हूं, "mscorlibex.dll," और यह वहां के सभी प्रकारों के लिए भी सच साबित होता है। मुझे लगता है कि यह एक हास्यास्पद बिंदु है, हालांकि, एकमात्र कारण यह है कि मैं ऐसा कर सकता हूं जो चुस्त हो जाएगा। –

8

मैं की तरह कुछ के साथ जाना चाहते हैं:

static bool IsFundamental(this Type type) 
{ 
    return type.IsPrimitive || type.Equals(typeof(string)) || type.Equals(typeof(DateTime)); 
} 

string की पसंद और DateTimethe types for which IsPrimitive returns true में योग के रूप में, हालांकि, एक व्यक्तिपरक बात के बाद से वहाँ कोई पूर्ण सूची है ... परम पसंद आपकी है (उदाहरण के लिए, आप decimal भी शामिल करना चाहेंगे); और इसे निश्चित रूप से दस्तावेज किया जाना चाहिए (कम से कम एक टिप्पणी में, अधिमानतः एक एक्सएमएल एक)।

4

इस question में जानकारी के आधार पर, आप निम्न कोड का उपयोग कर ऐसा कर सकते हैं:

public static class TypeExtensions 
{ 
    private static List<byte[]> tokens = new List<byte[]>() 
    { 
     new byte[] {0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89}, 
     new byte[] {0x31, 0xbf, 0x38, 0x56, 0xad, 0x36, 0x4e, 0x35}, 
     new byte[] {0xb0, 0x3f, 0x5f, 0x7f, 0x11, 0xd5, 0x0a, 0x3a} 
    }; 

    public static bool IsFrameworkType(this Type type) 
    { 
     if (type == null) { throw new ArgumentNullException("type"); } 

     byte[] publicKeyToken = type.Assembly.GetName().GetPublicKeyToken();  

     return publicKeyToken != null && publicKeyToken.Length == 8 
      && tokens.Contains(publicKeyToken, new ByteArrayEqualityComparer()); 
    } 
} 

सार्वजनिक कुंजी टोकन के सेट (.NET 4.0 सहित) .NET 2.0 और उच्चतर के लिए मान्य हैं।

public class ByteArrayEqualityComparer : EqualityComparer<byte[]> 
{ 
    public override bool Equals(byte[] x, byte[] y) 
    { 
     return x != null && y != null 
        && x.Length == 8 && y.Length == 8 
        && x[0] == y[0] 
        && x[1] == y[1] 
        && x[2] == y[2] 
        && x[3] == y[3] 
        && x[4] == y[4] 
        && x[5] == y[5] 
        && x[6] == y[6] 
        && x[7] == y[7]; 
    } 

    public override int GetHashCode(byte[] obj) 
    { 
     return obj.GetHashCode(); 
    } 
} 

फिर आप की तरह इस विधि का प्रयोग करेंगे: ByteArrayEqualityComparer वर्ग की तरह लग रहा

Debug.WriteLine("Is type `string` a .NET Framework type? {0}", 
    typeof(string).IsFrameworkType()); 
0

ऐसा लगता है कि आपको लगता है कि आप अपने आप को सब कुछ से बना प्रकार के बीच भेद करने के लिए एक की जरूरत है। बस, है कि आप अपने प्रकारों में से प्रत्येक पर डाल कस्टम विशेषता बनाने के इस तरह:

[CustomAttribute] 
struct MyDataType 
{ 
.... 
} 

एक अन्य विकल्प एक अंतरफलक है कि अपने स्वयं के कस्टम प्रकार के सभी लागू बनाने के लिए है। फिर यह देखना आसान है कि आपको if (x is ICustom) ... करके केवल उस उदाहरण के साथ कुछ विशेष करने की आवश्यकता है या नहीं।

यदि यह उन सब को एक ही नाम स्थान या विधानसभा में डालने के लिए संभव है, तो वे भी प्रतिबिंब के साथ जांच करने के लिए आसान कर रहे हैं।

+0

इस दृष्टिकोण के साथ समस्या यह है कि आप (और आपकी टीम के सभी को) को तब भी इस विशेषता को हर प्रकार के निर्माण में जोड़ना याद रखना होगा। आखिरकार यह रखरखाव सिरदर्द का कारण बन जाएगा जब कोई ऐसा करने के लिए भूल जाता है और चीजें गलत व्यवहार करना शुरू कर देती हैं। –

+0

स्कॉट: कुछ ह्यूरिस्टिक का उपयोग करने के बजाय अपने नियंत्रण में कुछ भरोसा करना बेहतर है जो एमएस पर निर्भर करता है कि अगले संस्करण में कुछ बदल नहीं रहा है। – Gabe

+0

यह अभी भी लंबे समय तक एक प्रमुख रखरखाव दुःस्वप्न प्रस्तुत करता है। फ्रेमवर्क के बाद के संस्करणों में माइक्रोसॉफ्ट की सार्वजनिक सार्वजनिक टोकन बदलने की संभावना पतली है हालांकि यह हो सकती है। –

0

आप द्वारा प्राप्त करने के लिए प्रकार या नीचे के रूप में विधानसभा का पूरा नाम की जाँच करके सक्षम हो सकता है,

if(obj.GetType().Assembly.FullName.Contains("MyAssembly")) 
{ 
    //User-defined type 
} 
else if(obj.GetType().FullName.StartsWith("System.")) 
{ 
    //.NET type 
} 
0

सबसे आसान तरीका मैं पीछा किया इसकी एक की अगर यह पता लगाने की नाम स्थान सत्यापित करने के लिए है आपके कस्टम प्रकार। उदाहरण के लिए, आपका नेमस्पेस "YourCompany.YourDepartment" हो सकता है और इसे प्रकार के नामस्थान के विरुद्ध सत्यापित किया जा सकता है।

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