2011-02-02 10 views
6

बेवकूफ शीर्षक के बारे में क्षमा करें, यह नहीं पता था कि यहसी #: एक गैर-जेनेरिक वर्ग के भीतर दो अमूर्त सूचियों का कार्यान्वयन?

मैं एक वर्ग बना रहा हूं जिसमें एक ही प्रकार की दो सूचियां हैं। इसका उपयोग दूसरी सूची में पहली सूची में ऑब्जेक्ट के संदर्भ की प्रतिलिपि बनाने के लिए किया जाता है।

हालांकि दोनों सूचियां एक ही प्रकार के होंगी (उसी प्रकार की वस्तु को पकड़ें) यह कक्षा प्रत्येक बार प्रारंभ होने पर अलग हो सकती है।

तो मुझे लगता है कि मुझे सूची प्रकारों को किसी प्रकार की सार सूची के रूप में बनाना चाहिए। मैं यह सुनिश्चित करना चाहता हूं कि इंस्टेंट किए जाने पर उन्हें दृढ़ता से टाइप किया जाएगा (लेकिन समस्याग्रस्त होने पर उत्तराधिकारी नहीं)। समस्या उस विधि के अंदर है जो चयनित आइटम को सूची 1 से सूची 2 में परिवर्तित करती है, सार सूची प्रकार सामान्य रूप से इसके लिए विधियां नहीं होती हैं।

मुझे लगता है कि सामान्य समाधान क्लास जेनेरिक (क्लासनाम <T> चीज़) बनाना होगा, लेकिन मुझे यकीन नहीं है कि मैं ऐसा कर सकता हूं (कम से कम मुझे नहीं पता कि कैसे) क्योंकि इस वर्ग को एक WPF UserControl प्राप्त होता है।

public partial class SubsetSelectionLists : UserControl 
{ 
    public static DependencyProperty SetCollectionProperty = DependencyProperty.Register("SetCollection", typeof("Need a abstract list type here"), typeof(SubsetSelectionLists)); 
    public static DependencyProperty SubsetCollectionProperty = DependencyProperty.Register("SubsetCollection", typeof("Need a abstract list type here"), typeof(SubsetSelectionLists)); 

    public "Need a abstract list type here" SetCollection 
    { 
     get 
     { 
      return ("Need a abstract list type here") GetValue(SetCollectionProperty); 
     } 
     set 
     { 
      SetValue(SetCollectionProperty, value); 
     } 
    } 

    public "Need a abstract list type here" SubsetCollection 
    { 
     get 
     { 
      return ("Need a abstract list type here")GetValue(SubsetCollectionProperty); 
     } 
     set 
     { 
      SetValue(SubsetCollectionProperty, value); 
     } 
    } 

    public SubsetSelectionLists() 
    { 
     InitializeComponent(); 
     SubsetSelectiongrid.DataContext = this; 
    } 

    private void selectionBtnClick(object sender, RoutedEventArgs e) 
    { 
     SubsetCollection.AddTheseItems(SET.SelecctedItems) 
    } 

    private void removeBtnClick(object sender, RoutedEventArgs e) 
    { 
     SUBSET.RemoveTheseItems(SUBSET.SelectedItem); 
    } 
} 

संपादित करें: समाधान

कुछ जवाब मुझे एक सामान्य वर्ग बनाने के इष्टतम समाधान की दिशा में इशारा किया

यहाँ कोड है। हालांकि यह WPF में समस्याग्रस्त हो सकता है। आपको शीर्ष स्तर जेनेरिक वर्ग पर एक्सएएमएल छोड़ना होगा।

इसका मतलब यह होगा कि आप विशिष्ट बाल वर्गों में एक्सएएमएल कर सकते हैं जो कुछ ऐसा नहीं है जिसे आप करना चाहते हैं (जब तक कि कोड केवल कुछ नहीं है जिसे आप फिर से उपयोग करेंगे लेकिन देखो परिवर्तनीय है)। आप मुझे लगता है कि कोड का उपयोग कर नियंत्रण डिजाइन भी किया जा सकता है, लेकिन मुझे यकीन नहीं है कि यह कितना प्रभावी होगा।

मुझे आईलीस्ट ऑब्जेक्ट की ओर इशारा किया गया था जो एक सार सूची है जिसे कई अन्य लोगों का उत्तराधिकारी है और मैं इसका उपयोग कर रहा हूं। यह एक हैक का थोड़ा सा है लेकिन चूंकि इसका उपयोग ओपन लाइब्रेरी में नहीं किया जाएगा, मैं इसके साथ ठीक हूं। अन्यथा मैं जेनेरिक रूट का उपयोग करूंगा।

+0

कोई कारण नहीं है कि आप इसे linq में नहीं कर सकते हैं? क्या आपके पास .NET के अपने संस्करण पर सीमाएं हैं? – phillip

+0

क्या .NET संस्करण। लिंक और जेनेरिक – Hawxby

+2

ऐसा करने में सक्षम होना चाहिए मुझे समझ में नहीं आता कि linq यहां मेरी मदद कैसे कर सकता है? कृपया इसके जवाब के लिए उत्तर दें। मैं .NET 3.5 का उपयोग कर रहा हूं लेकिन शायद 4.0 –

उत्तर

3

मुझे नहीं पता कि डिजाइनर सामान्य नियंत्रण वाले उपयोगकर्ता नियंत्रण के साथ कितनी अच्छी तरह से खेलते हैं।यदि यह एक समस्या है (जो मुझे लगता है), उस से दूर जाने का एक तरीका संग्रह IList का खुलासा करना है, लेकिन अभी भी List<T> का उपयोग करें जो स्टोरेज में टाइप सुरक्षा में रनटाइम में बनाए गए हैं (कोड नमूना केवल सूची ऑब्जेक्ट को शामिल करने के लिए कम किया गया है निर्माण और उन्हें उजागर के लिए गुण; DependencyProperty के लिए कोड जोड़ सकते हैं और इतने पर के रूप में आवश्यक):

public class YourControl : UserControl 
{ 

    // this method will set up the internal lists for accepting 
    // objects of the specified type only 
    public void SetListType(Type containedType) 
    { 
     var listType = typeof(List<>).MakeGenericType(new[] { containedType }); 
     SetCollection = (IList)Activator.CreateInstance(listType); 
     SubsetCollection = (IList)Activator.CreateInstance(listType); 
    } 
    public IList SetCollection { get; private set; } 
    public IList SubsetCollection { get; private set; } 
} 

// usage example: 
theControl.SetListType(typeof(string)); 
theControl.SetCollection.Add("some string"); // works ok 
theControl.SetCollection.Add(42); // fails, 42 is not a string 

स्पष्ट नकारात्मक पक्ष यह है कि SetCollection और SubsetCollection बेनकाब "untyped" object सूचियों है।

+0

ठीक है यह एक उपयोगी था। मैं IList का उपयोग कर सकता हूं क्योंकि यह ऐड विधि लागू करता है। मैंने बस इलिस्ट को हर जगह रखा है, यह कहता है, "यहां एक अमूर्त सूची प्रकार की आवश्यकता है" और फिर सुनिश्चित करें कि मैं एक सूची बांधता हूं (मेरे मामले में अवलोकन करने योग्य चयन) जो आईलीस्ट को विरासत में लेता है। प्रत्येक सूची टाइप-सुरक्षित होगी लेकिन मुझे नहीं लगता कि उनके पास एक ही प्रकार है। –

2

जैसा कि आप कहते हैं, एक सामान्य वर्ग यह प्राप्त करने का तरीका है और आप इसे गैर-जेनेरिक पेरेंट क्लास से विरासत में प्राप्त करते समय कर सकते हैं, उदाहरण के लिए

partial class GenericClass1<T> : UserControl 
    { 
    private List<T> _list; 
    } 

संपादित नीचे

टिप्पणी टाइप वर्गों है कि ऊपर कक्षा में सामान्य प्रकार को ठीक (और डिजाइनर द्वारा इस्तेमाल किया जा सकता है) को परिभाषित करें पर आधारित है, यानी

partial class IntClass1 : GenericClass1<int> {} 

partial class StringClass1 : GenericClass1<string> {} 

.... 

बेशक यह केवल वास्तव में काम करता है यदि आपके पास अपनी सूचियों में सीमित/स्थिर सेट प्रकार हैं जिन्हें आप अपनी सूचियों में रखना चाहते हैं

+0

पर अपग्रेड हो जाएगा जब तक कि गैर-जेनेरिक पैरेंट WPF UserControl क्लास नहीं है। मैंने ऐसा करने की कोशिश की, यह आंशिक वर्ग होने पर ध्यान दें और कक्षा के पुनर्विक्रय को एक्सएएमएल में घोषित किया गया है। मुझे दावा है कि आप सामान्य उपयोगकर्ता नियंत्रण नहीं कर सकते हैं। –

+0

एक बार जब आप अपनी जेनेरिक क्लास को परिभाषित कर लेते हैं तो क्या आप टाइप किए गए सबक्लास को परिभाषित नहीं कर सकते हैं जो WPF उपयोगकर्ता नियंत्रण के रूप में काम करेगा? –

+0

समस्या यह है कि मैं आंशिक के आधे हिस्से को जेनेरिक के रूप में परिभाषित नहीं कर सकता, जो कोड XAML में है। कक्षा सिर्फ संकलित नहीं होगी। मैं एक्सएएमएल भाग के बिना कक्षा बना सकता था लेकिन फिर मुझे कोड में या सभी उप-वर्गों में दिखने के लिए (सभी उप-वर्गों में भी वही होगा) जो मुझे नहीं करना चाहता था। मैं आपकी पोस्ट को उपयोगी के रूप में चिह्नित कर रहा हूं। –

3

ऐसा कुछ या मैं sh निशान के चौड़े ओटिंग?

public partial class SubsetSelectionLists<T> : UserControl 
{ 
    public List<T> SetCollection { get; set; } 

    public List<T> SubsetCollection { get; set; } 

    public SubsetSelectionLists() 
    { 
     SubsetSelectiongrid.DataContext = this; 
    } 

    private void selectionBtnClick(object sender, RoutedEventArgs e) 
    { 
     SubsetCollection.AddRange(SetCollection); 
    } 

    private void removeBtnClick(object sender, RoutedEventArgs e) 
    { 
     SubsetCollection.RemoveAll(x => SetCollection.Contains(x)); 
    } 
} 
+0

जैसा कि मैंने अपने प्रश्न में कहा था, वैसे ही यह सामान्य रूप से किया जाएगा। हालांकि यह एक WPF उपयोगकर्ता नियंत्रण से विरासत में आता है, यह काम नहीं कर रहा है। –

+0

मैं वर्ग को अमूर्त के रूप में चिह्नित करता हूं और उसके बाद नियंत्रण कक्षाएं बनाता हूं जो इससे प्राप्त होते हैं ताकि आप एक प्रकार निर्दिष्ट कर सकें। – Hawxby

+0

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

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