2012-10-30 12 views
8

मान लीजिए मैं निम्नलिखित वर्ग है:सी # जेनेरिक और शून्य मूल्य मान को समझना। लौटें नल या नल

public class GenericClass<T> 
{ 
    public T Find() 
    { 
     //return T if found otherwise null or Nullable<T> 
    } 
} 

कहीं मैं एक class साथ मेरी कक्षा T का उपयोग कर विशेषज्ञ करना चाहते हैं एक struct साथ, दूसरी बार। मुझे यह issue का सामना करना पड़ रहा है: यदि T प्रकार struct होने के लिए प्रतिबंधित नहीं है, तो मैं Nullable<T> वापस नहीं कर सकता।

मैं अपने Find विधि के एक कार्यान्वयन काम करता है कि अगर T दोनों एक class या एक struct साथ विशेष है प्रदान करना चाहते हैं। Find विफल होने पर, null वापस लौटना चाहूंगा यदि T अन्यथा Nullable<T> है।

क्या यह प्रतिबिंब का उपयोग किए बिना संभव है? यदि हां कैसे?

+0

आप वापस नहीं लौट सकते टी या Nullable अगर वापसी प्रकार टी – fsimonazzi

उत्तर

15

आप default(T) वापस कर सकते हैं।

कक्षा के लिए, यह null होगा। किसी भी Nullable<T> के लिए, यह एक मूल्य के बिना Nullable<T> होगा (प्रभावी रूप से null)।

कहा जा रहा है, अगर आप इस एक struct और न प्रकार के रूप में एक Nullable<T> के साथ उपयोग, default(T) struct का डिफ़ॉल्ट मान हो जाएगा।

: यानी आप यहाँ प्रेरणा के रूप में ढांचे इस्तेमाल कर सकते हैं, और एक TryXXX विधि है, -


आप किसी भी वर्ग या struct के लिए समान रूप से इस काम बनाना चाहते हैं, आप की संभावना दो मानों वापस जाने के लिए की आवश्यकता होगी

public bool TryFind(out T) 

तब आप default(T) का उपयोग कर सकते हैं जब मान नहीं मिलता है, और झूठी वापसी होती है। यह शून्य प्रकारों की आवश्यकता से बचाता है। आप भी इस एक Tuple<bool, T> या इसी तरह के लौटने अगर आप बाहर पैरामीटर से बचना चाहते थे लिख सकता है, अर्थात:

public Tuple<bool, T> Find() 

एक अंतिम विकल्प, संभावित, अपने वर्ग गैर सामान्य बनाने के लिए हो सकता है, तो की एक जोड़ी का उपयोग सामान्य तरीके:

class YourClass // Non generic 
{ 
    public T FindReference<T>() where T : class 
    { 
     // ... 
     return null; 
    } 

    public Nullable<T> FindValue<T>() where T : struct 
    { 
     // ... 
     return default(T); 
    } 
} 

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

public Boolean Find(out T result) 
{ 
    // Pseudo code 
    if (FindItem == true) 
    { 
     result = ItemFound; 
     return true; 
    } 
    result = default(T); 
    return false; 
} 

क्यों:

+0

है तकनीकी तौर पर, 'डिफ़ॉल्ट (टी)' एक 'Nullable नहीं लौटेगा की तरह कुछ के लिए जाना होगा' जब 'int' को सामान्य तर्क के रूप में आपूर्ति की जाती है क्योंकि ओपी चाहता है, लेकिन यह निश्चित रूप से आपको वहां से अधिकतर तरीके से प्राप्त करता है। वास्तव में, ओपी चाहता है कि वास्तव में प्राप्त करने का एकमात्र तरीका दो सामान्य कार्यान्वयन, एक मूल्य प्रकार के लिए, और संदर्भ प्रकारों के लिए एक प्रदान करना होगा। – Tejs

+0

@Tejs। इसलिए यदि मुझे संख्या प्रकार के साथ टी को विशेषज्ञता देने की आवश्यकता है, तो क्या मुझे सामान्य समाधान प्राप्त करने के लिए आउट पैरामीटर का उपयोग करने के लिए मजबूर किया गया है? यदि टी int है तो डिफ़ॉल्ट वापसी क्या होती है? – Heisenbug

+0

@Tejs हां - यही वह है जो मैं अंतिम वाक्य में कहने की कोशिश कर रहा था - 'डिफ़ॉल्ट (टी) '' शून्य '' प्रदान करेगा यदि आप सामान्य प्रकार, thoguh के रूप में' Nullable 'का उपयोग करते हैं। –

2

मैं निम्नलिखित समाधान का प्रयोग करेंगे? क्योंकि Nullable<T> केवल एक स्ट्रक्चर स्वीकार करता है और उपर्युक्त विधि दोनों वर्गों और structs का समर्थन करता है।

+1

+1, और इस मुहावरे को आम तौर पर 'TryXXXX' नाम दिया जाता है, इसलिए' TryGetValue' या 'TryFind' उपयुक्त होगा। – user7116

+0

@sixlettervariables हाँ, आप सही हैं। लेकिन मैं उस नाम पर रहा जो हेइज़ेनबर्ग का इस्तेमाल करता था। –

0

रीड ने कहा कि आप default(T) वापस कर सकते हैं।

मेरी राय में इसका एक बड़ा नुकसान है: यदि आपकी विधि बताती है कि default(T) वापस आइटम नहीं मिला है, तो आप मान प्रकारों के लिए डिफ़ॉल्ट मान वापस करने की क्षमता खो देते हैं (उदा।0Find<int> के लिए लौटने पर आम तौर पर एक पूरी तरह से वैध वापसी मूल्य हो सकता है)।

मैं नहीं बल्कि इस

public class GenericClass<T> 
{ 
    public Option<T> Find() 
    { 
     //return Option.Some(item) if found otherwise Option.None<T>() 
    } 
} 

public static class Option 
{ 
    public static Option<T> None<T>() 
    { 
     return new Option<T>(default(T), false); 
    } 

    public static Option<T> Some<T>(T value) 
    { 
     return new Option<T>(value, true); 
    } 
} 

public sealed class Option<T> 
{ 
    private readonly T m_Value; 
    private readonly bool m_HasValue; 

    public void Option(T value, bool hasValue) 
    { 
     m_Value = value; 
     m_HasValue = hasValue; 
    } 

    public bool HasValue 
    { 
     get { return m_HasValue; } 
    }   

    public T Value 
    { 
     get { return m_Value; } 
    } 
} 
+1

यह प्रभावी रूप से 'Nullable 'का एक नया रूप लिख रहा है जो कि structs के लिए बाध्य नहीं है - अब, यदि सी # पैटर्न मिलान कर रहा है, तो यह जाने का तरीका होगा;) –

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