2009-07-27 11 views
6

मेरे पास एक समान विधि के साथ एक संग्रह वर्ग है जिसे मैं प्रत्येक आइटम के बीच समानता जांच करने के लिए एक विधि में पास करना चाहता हूं।क्या मैं सी # जेनेरिक बाधाओं में 'सुपरटेप' संबंध निर्दिष्ट कर सकता हूं?

public delegate bool EqualityComparer<T>(T x, T y); 

public class Collection<T> 
{ 
    //... 

    public bool Equals<U>(Collection<T> other, EqualityComparer<U> eq) where T : U 
    { 
     // code using eq delegate to test equality between 
     // members of this and other collection 
    } 
} 

दुर्भाग्य से, संकलक इस पर borks ('Collection.Equals()' प्रकार पैरामीटर 'को परिभाषित नहीं करता टी: इसके अलावा, मैं प्रतिनिधि प्रकार टी खुद के रूप में टी की सुपर-क्लास पर संचालित करने के लिए और साथ ही अनुमति देना चाहते हैं ')। क्या इस प्रकार की बाधा/संचालन को निर्दिष्ट करने का कोई तरीका है?

उत्तर

4

नहीं, मुझे डर है कि आप इस तरह की बाधा निर्दिष्ट नहीं कर सकते हैं। (मैं इसे अवसर पर भी चाहता था।)

आप एक गैर सामान्य वर्ग यद्यपि में दो प्रकार के मानकों के साथ एक स्थिर सामान्य विधि लिख सकते हैं:

public delegate bool EqualityComparer<T>(T x, T y); 

public class Collection 
{ 
    public static Equals<T, U>(Collection<T> first, 
           Collection<T> second, 
           EqualityComparer<U> comparer) where T : U 
    { 

    } 
} 

और तुम भी है कि कॉल कर सकते हैं सामान्य वर्ग पर एक उदाहरण विधि यदि आप चाहें:

// Implementing the static method: 
return first.Equals(second, new EqualityComparer<T>(comparer)); 

जहां संग्रह का उदाहरण विधि सिर्फ होगा:

public bool Equals(Collection<T> other, EqualityComparer<T> eq) 
{ 
    // ... 
} 

यह के लिए उपलब्ध contravariance का उपयोग करता है सी # 2 से प्रतिनिधियों को बनाते हैं।

+0

क्या यह संभव होने के लिए समझ में आता है? अनुमान से इसे संभव नहीं बनाना मुश्किल होगा क्योंकि दो घोषणाओं को पूरे प्रोजेक्ट में फैलाया जा सकता है, या यहां तक ​​कि निर्दिष्ट नहीं किया जा सकता है – Dykam

+1

हां, यह सही समझ में आता है - आप निर्दिष्ट कर सकते हैं कि एक प्रकार पैरामीटर * subclass * होना चाहिए कुछ और, तो दूसरी तरफ क्यों नहीं? (जावा इसे 'टी सुपर फू' का उपयोग करके 'टी सुपर फू' का उपयोग करता है, बीटीडब्ल्यू, बीटीडब्ल्यू।) –

+0

आह - मुझे लगता है कि आप एक राइडर के रूप में जो लिख रहे थे उसे रखने के लिए आप अपना जवाब संपादित कर रहे थे :) – ShuggyCoUk

0

यदि आप स्पष्ट रूप से टाइप पैरामीटर को यू के उत्तराधिकारी वर्ग के रूप में चाहते हैं, तो आपको जेनिक्स की आवश्यकता नहीं है, बल्कि यू को पैरामीटर के औपचारिक प्रकार के रूप में उपयोग करें। और वहाँ polimorfism में kicks! :)

1

जैसा कि जॉन ने कहा था कि आप कक्षा के स्तर पर घोषित होने के बाद इस तरह की बाधा के भीतर टी का संदर्भ नहीं दे सकते।

आप संग्रह के निजी राज्य के लिए उपयोग के बिना विधि लिख सकते हैं (या उनके जा रहा है आंतरिक के साथ) तो आप तो जैसे पुनर्लेखन कर सकते हैं:

public class Collection<T> 
{ 
    ... 
} 

public static class CollectionExtentions 
{ 
    public static bool Equals<T,U>(
      this Collection<T> first, 
      Collection<T> other, 
      EqualityComparer<U> eq) where T : U 
    { 
      ... // legal to use eq here on the T values with collections 
    } 
} 

संयोग से मैं आप अपने खुद के बजाय Func<T,T,bool> का उपयोग करने का सुझाव नामित प्रतिनिधि

+0

यह .NET 2 में है, इसलिए Func उपलब्ध नहीं है :( – thecoop

+0

आह - डाउनर :(आप उस राइडर को प्रश्न में जोड़ना चाहेंगे (क्योंकि स्पष्ट रूप से आप एक्सटेंशन विधि के वाक्यविन्यास का उपयोग करने में सक्षम नहीं होंगे, इसलिए जॉन का सुझाव उदाहरण विधि द्वारा उपयोग की जाने वाली स्थिर विधि का सर्वोत्तम है) – ShuggyCoUk

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

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