2013-02-13 38 views
8

मुझे आशा है कि प्रश्न सही है, तो चलो आपको एक उदाहरण दें। निम्नलिखित सामान्य विधि कल्पना कीजिए:वीएस मुझे चेतावनी क्यों देता है कि टाइपफ़ोफ़ (टी) एक सामान्य विधि में प्रदान नहीं किया गया प्रकार है जहां टाइप पैरामीटर टी लागू करने के लिए प्रतिबंधित है?

public abstract class Base : IDisposable 
{ 
    public static IEnumerable<T> GetList<T>() 
     where T : Base 
    { 
     // To ensure T inherits from Base. 
     if (typeof(T) is Base) 
      throw new NotSupportedException(); 

     // ... 
    } 
} 

MSDN कीवर्ड where को प्रतिबंधित करता है प्रकार पैरामीटर T प्रकार Base का होना या इस वर्ग से इनहेरिट करना के अनुसार।

[...] एक जहां खंड एक आधार वर्ग बाधा, जिसमें कहा गया है कि एक प्रकार का एक आधार वर्ग के रूप में निर्दिष्ट वर्ग में शामिल होना आवश्यक है (या उस वर्ग में ही हो सकता है) के क्रम में कर सकते हैं एक प्रकार के रूप में प्रयोग की जाने वाली उस सामान्य प्रकार के लिए तर्क।

public static T GetFirst() 
    where T : Base 
{ 
    // Call GetList explicitly using Base as type parameter. 
    return (T)GetList<Base>().First(); 
} 

तो जब निम्नलिखित पिछले कोड typeof(T)Base लौटना चाहिए, ऐसा नहीं होना चाहिए:

इसके अलावा इस कोड को संकलित करता है? विजुअल स्टूडियो फिर मुझे यह चेतावनी क्यों प्रिंट करता है?

चेतावनी CS0184: दी गई अभिव्यक्ति कभी उपलब्ध नहीं है ('डेमो.बेस') प्रकार।

+0

आप क्या करना चाहते हैं? यह सुनिश्चित करना कि 'बेस' से' टी' विरासत बेकार है, क्योंकि सामान्य बाधा पहले ही यह सुनिश्चित करती है। – CodesInChaos

+0

बाधा यह सुनिश्चित करती है कि 'टी' या तो 'बेस' ** से प्राप्त होता है या **' बेस 'ही है। मैं केवल 'बेस' से प्राप्त करने के लिए 'टी 'चाहता हूं। – Carsten

उत्तर

13

typeof(whatever) हमेशा प्रकार Type का एक उदाहरण देता है। TypeBase से प्राप्त नहीं हुआ है।

if(typeof(T) == typeof(Base)) 
    throw new NotSupportedException("Please specify a type derived from Base"); 

कुछ ऐसा लग रहा है ऐसा लगता है जैसे एक ही इस है:

if(variableOfTypeT is Base) 

लेकिन वह एक अलग अर्थ है

क्या आप चाहते हैं यह है।
पहला कथन (typeof(Base) के साथ) केवल true है यदि TBase है। यह Base से प्राप्त किसी भी प्रकार के लिए false होगा।
दूसरा कथन (variableOfTypeT is Base) आपकी कक्षा में हमेशा true है, क्योंकि Base से प्राप्त कोई भी वर्ग अपनी बेस क्लास के लिए चेक के लिए true लौटाएगा।

+0

विकल्प काम नहीं करता है ... 'टी' एक प्रकार पैरामीटर है लेकिन एक चर की तरह प्रयोग किया जाता है;) लेकिन पहला दृष्टिकोण काम करता है ... मुझे यह कैसे याद आया ?! कभी-कभी समाधान बहुत आसान होता है: डी – Carsten

+0

@Aschratt: आप सही हैं, मैंने इसे सही किया है। –

1

ऐसा नहीं है कि आप विरासत की जांच कैसे करते हैं।

typeof(T)System.Type प्रकार का है, यह Base नहीं है। यह देखने के लिए कि क्या टी बेस से लिया गया है, आपको IsSubclassOf method का उपयोग करना चाहिए, जैसे:

if(typeof(T).IsSubclassOf(typeof(Base)) ... 
+0

ध्यान दें कि 'टी == बेस' – CodesInChaos

+0

मैंने सोचा था कि यह बिंदु था। प्रतिबंध के कारण, ओपी पहले से ही जानता है कि टी या तो आधार है या इससे व्युत्पन्न है। – zmbq

+0

मैं जानना चाहता था कि 'टी' * * बेस 'है, यह सुनिश्चित करने के लिए कि उस सारणी वर्ग के केवल कार्यान्वयन विधि को पास हो जाएं। 'IsSubclassOf' उस चेक को निष्पादित करेगा जिसे मैंने पहले से ही' कहां 'बाधा के साथ व्यक्त किया है। – Carsten