2011-09-28 13 views
5

को हटाने के लिए एक सामान्य सबक्लास कैसे बनाएं I मेरे पास दो कक्षाएं चेकबॉक्स लिंक से ली गई हैं और दूसरा ड्रॉपडाउनलिस्ट से ली गई है। उनके अंदर कोड बिल्कुल वही है। एकमात्र अंतर यह है कि मुझे उन स्थानों पर पहले स्थान की आवश्यकता है जहां मुझे ड्रॉपबॉक्स सूची दिखाने और ड्रॉपडाउन सूची दिखाने के लिए दूसरा स्थान दिखाना है। आप देख सकते हैं के रूप में आंतरिक कोड बिल्कुल वैसा ही है जो मुझे से बचना चाहते हैं हैडुप्लिकेट कोड

using System; 
using System.Collections.ObjectModel; 
using System.Web.UI.WebControls; 

    namespace Sample 
    { 
     public class MyCheckBoxList : CheckBoxList 
     { 
      public int A { get; set; } 
      public int B { get; set; } 
      protected override void OnLoad(EventArgs e) 
      { 
       //dummy task 
       Collection<int> ints = new Collection<int>(); 
       //........ 
       this.DataSource = ints; 
       this.DataBind(); 
      } 
     } 
    } 

दूसरा एक

using System; 
using System.Collections.ObjectModel; 
using System.Web.UI.WebControls; 

namespace Sample 
{ 
    public class MyDropDownList : DropDownList 
    { 
     public int A { get; set; } 
     public int B { get; set; } 
     protected override void OnLoad(EventArgs e) 
     { 
      //dummy task 
      Collection<int> ints = new Collection<int>(); 
      //........ 
      this.DataSource = ints; 
      this.DataBind(); 
     } 
    } 
} 

अब: नीचे मेरी कोड है। कोड डुप्लिकेट को हटाने के लिए मैं इसके लिए एक सामान्य कक्षा कैसे बना सकता हूं?

+3

+1। आपका प्रश्न यहां बेहतर अनुकूल हो सकता है हालांकि: http://codereview.stackexchange.com/ –

+0

@ किलीनारो: कोडरेव्यू के बारे में जानने के लिए कूल, यह नहीं पता था कि यह अस्तित्व में है। एसओ के लिए यह एक बुरा मैच मत सोचो। अच्छा सवाल मुझे लगता है। +1 –

उत्तर

3

आप एक तृतीय श्रेणी के

public class Entity 
{ 
    public int A { get; set; } 
    public int B { get; set; } 
    Collection<int> GetCollection() 
    { 
     //dummy task 
     Collection<int> ints = new Collection<int>(); 
     //........ 
     return ints; 
    } 
} 

और फिर अन्य वर्गों

public class MyDropDownList : DropDownList 
{ 
    public MyDropDownList() { Entity = new Entity(); } 

    public Entity {get;set;} 
    protected override void OnLoad(EventArgs e) 
    { 
     this.DataSource = Entity.GetCollection(); 
     this.DataBind(); 
    } 
} 
+0

लेकिन इससे मेरी संपत्तियां Entity.A और Entity.B जैसी होती हैं। मैं इससे बचना चाहता हूं। मैं सीधे अपने एएसपीएक्स पृष्ठों से गुण चाहता हूं। –

+0

@ रॉक: एंटिटी को एन्सेप्लेट करें, इसे निजी बनाएं और इसे एक्सेस करने के लिए अपनी कक्षा में एक संपत्ति बनाएं। रचना का उपयोग करने के लिए – Arjang

+0

+1, केवल एक चीज छोड़कर एन्टीसिटी का उपयोग करके एंटिटी आंतरिक बना रही थी, इसलिए बाहरी रूप से इसकी आवश्यकता नहीं है – Arjang

0

आप नहीं कर सकते में इसका इस्तेमाल करते हैं बना सकते हैं क्योंकि सी # कार्यान्वयन के कई विरासत का समर्थन नहीं करता है (और आप पहले से ही उपवर्गीकरण कर रहे हैं)। आप कुछ कोड को तीसरे वर्ग में दोबारा कर सकते हैं और आपके प्रत्येक वर्ग में एक उदाहरण और प्रतिनिधि कॉल है।

आप इस तरह कुछ कोशिश कर सकते हैं: http://www.codeproject.com/KB/architecture/smip.aspx, लेकिन यह बहुत सारे काम की तरह दिखता है।

+0

सिर्फ इसलिए कि मैं उत्सुक हूं और वास्तव में कोई जानकारी नहीं है, क्या आप इस बात को विस्तारित करेंगे कि कोई व्यक्ति प्रतिनिधियों का उपयोग कैसे प्राप्त कर सकता है ओपी की तलाश है? –

+1

मैं सिर्फ तीसरे ऑब्जेक्ट पर कॉल का प्रतिनिधित्व करने का मतलब था। मैं सी # के प्रतिनिधि का जिक्र नहीं कर रहा था। स्पष्टीकरण के लिए –

+0

धन्यवाद। मैं समझता हूं तुम्हारा क्या मतलब है! –

0

आप रचना का उपयोग करते हैं, एक और वर्ग बनाएं जो इन दो वर्गों से संबंधित नहीं है, उसके बाद उसमें सामान्य कोड है, जब आपको किसी भी कक्षा में कोड का उपयोग करने की आवश्यकता होती है, तो आप इसे थोरूग भी इस्तेमाल कर सकते हैं एक इंटरफ़ेस विरासत का उपयोग करने की कोई ज़रूरत नहीं है।

अद्यतन: कोड के नीचे (संशोधित कोड पहले से ही meziantou द्वारा प्रदान की)

internal interface IEntity 
    { 
     int A { get; set; } 
     int B { get; set; } 
     Collection<int> GetCollection { get; } 
    } 

    internal class Entity : TrialBalanceHTMLToDataTable.TrialBalance.IEntity 
    { 
     public int A { get; set; } 
     public int B { get; set; } 
     public Collection<int> GetCollection 
     { 
      get{ 
      //dummy task 
      Collection<int> ints = new Collection<int>(); 
      //........ 
      return ints; 
      } 
     } 
    } 


    public class MyDropDownList : DropDownList 
    { 
     public MyDropDownList() { _Entity = new Entity(); } 

     private IEntity _Entity { get; set; } 
     protected override void OnLoad(EventArgs e) 
     { 
      this.DataSource = _Entity.GetCollection; 
      this.DataBind(); 
     } 
    } 
+1

-1 कहने के लिए कि एक इंटरफेस समस्या को हल करेगा; इंटरफ़ेस को लागू करने वाले दो वर्गों के बीच परिभाषाओं को अभी भी डुप्लिकेट किया जाएगा। लेकिन आपको यह सुझाव देने के लिए +1 मिलता है कि आम कोड दूसरे वर्ग में स्थानांतरित हो जाता है ... तो आप भी तोड़ते हैं! –

+0

@ किलीनारो: एलओएल :), इंटरफेस समस्याएं हल नहीं करते हैं, वे आपको उन्हें समान बनाने की अनुमति देते हैं! – Arjang

+0

@ किलीनारो: नहीं! सामान्य वर्ग इंटरफ़ेस को कार्यान्वित करेगा, अन्य दो वर्ग केवल उस वर्ग से बात करने के लिए इसका उपयोग करेंगे जो इसे लागू करता है, विचार दो अलग-अलग वर्ग – Arjang

0

यह प्रतीत होता है कि आप क्या हासिल करने के लिए कोशिश कर रहे हैं एक भी वर्ग के लिए है, कि MyDropDownList, गुण विरासत में करने में सक्षम हो गया है DropDownList से, और MyCheckBox कक्षा CheckBox कक्षा से गुणों का उत्तराधिकारी है, जबकि आपके दो मेरे * कक्षाओं में कुछ अतिरिक्त गुण हैं, जो समान होते हैं।

जैसा कि अन्य ने सुझाव दिया है, इसे पूरा करने का सबसे आसान तरीका Multiple Inheritance के माध्यम से होगा। विशेष रूप से, आपके उदाहरण में, इसका अर्थ है (संभवतः abstract) कक्षा जो MyDropDownList और MyCheckBox के बीच साझा विशेषताओं का वर्णन करती है, और फिर उन दो वर्गों को उनके संबंधित सिस्टम दोनों से प्राप्त होता है। वेब.यूआई। वेबकंट्रोल बेस के साथ-साथ यह "साझा किया गया " कक्षा। हालांकि, जैसा कि कहा गया है, C# doesn't support multiple inheritance. क्रिस ब्रूम से उस लिंक के माध्यम से:

एमआई वास्तव में उपयुक्त जगहों की संख्या वास्तव में काफी छोटी है। कई मामलों में, कई इंटरफेस विरासत इसके बजाय नौकरी मिल सकती है। अन्य मामलों में, आप encapsulation और प्रतिनिधिमंडल का उपयोग करने में सक्षम हो सकते हैं।

आपने Interfaces का उपयोग करने पर भी विचार किया होगा। जैसा कि आपने पाया होगा, के रूप में आपके समाधान के लिए अनुचित विकल्प होगा, एक इंटरफ़ेस केवल आपको परिभाषित करने की अनुमति देता है कि कक्षा में कुछ गुण और विधियां हैं, लेकिन यह नहीं कि गुण या विधियां कैसे परिभाषित की जाती हैं। तो फिर, यह डुप्लिकेट कोड को हटाने के लिए एक अनुचित विकल्प है।

आपके लिए इसका क्या अर्थ है? खैर, यदि आप MyDropDownList कक्षा लिखने की सोच रहे हैं जो myCustomDDLInstance.SelectedIndex और myCustomDDLInstance.A सिंटैक्स दोनों का समर्थन करता है, तो आपको थोड़ा "जादू" करना होगा। लेकिन तथ्य यह है कि आपकी भाषा जो आप करने की कोशिश कर रही है उसका समर्थन नहीं करती है, उसे लाल झंडा उठाना चाहिए! यह आवश्यक नहीं है, लेकिन यह एक मजबूत संकेतक होना चाहिए कि आप अपने डिज़ाइन को फिर से तैयार करना चाहें।

मेरा अनुमान है कि दो वर्गों का डुप्लिकेट हिस्सा अकेले खड़े हो सकता है क्योंकि यह अपनी तार्किक इकाई है। इसका मतलब है कि आप इन साझा गुणों और विधियों को पकड़ने के लिए अपनी खुद की कक्षा को उचित रूप से बना सकते हैं। यहाँ हम क्या मिलता है:

SampleControl.cs

public class SampleControl 
{ 
    public int A { get; set; } 
    public int B { get; set; } 

    public Collection<int> MysteryCollection 
    { 
     get 
     { 
      Collection<int> ints = new Collection<int>(); 
      //........ 
      return ints; 
     } 
    } 
} 

तो CSharp में तथ्य समर्थन एकाधिक वंशानुक्रम किया था, अपने MyDropDownList वर्ग DropDownList और SampleControl दोनों से विरासत सकता है और आप के लिए किया जाना था। लेकिन फिर, यह संभव नहीं है।

तो हम आपका लक्ष्य कैसे पूरा कर सकते हैं? यह थोड़ा उलझन में है, लेकिन आप अपने प्रत्येक कस्टम वर्ग में Encapsulate अपनी साझा संपत्तियों और विधियों को कर सकते हैं।

public class MyDropDownList : DropDownList 
{ 
    private SampleControl mySampleControl { get; set; } 

    public int A 
    { 
     get 
     { 
      return mySampleControl.A; 
     } 

     set 
     { 
      mySampleControl.A = value; 
     } 
    } 

    public int B 
    { 
     get 
     { 
      return mySampleControl.B; 
     } 

     set 
     { 
      mySampleControl.B = value; 
     } 
    } 

    public MyDropDownList() 
    { 
     mySampleControl = new SampleControl(); 
    } 

    protected override void OnLoad(EventArgs e) 
    { 
     //dummy task 
     this.DataSource = mySampleControl.MysteryCollection; 
     this.DataBind(); 
    } 
} 

इस तरह से तैयार किया गया एक वर्ग है, जबकि एक सा जटिल, प्रकार वाक्य रचना है कि आप देख रहे हैं को पूरा करना चाहिए: यहाँ MyDropDownList वर्ग (टिप्पणी के लिए एक उदाहरण है कि MyCheckBoxList ही, बस बदलने के वर्ग के नाम होगा है के लिए।

एक अंतिम नोट के रूप में मैं दृढ़ता से आप के लिए कम से कम अपने डिजाइन फिर से जांच और अगर वहाँ आप अपने वर्ग पदानुक्रम के पास जाने के लिए एक बेहतर तरीका है देखने पर विचार प्रोत्साहित करेगा। मेरी सिफारिश है कि यदि आपकी साझा गुण एक तार्किक इकाई के रूप में अपने आप पर मौजूद हो सकता है, वे शायद अपनी खुद की कक्षा होनी चाहिए। और यदि ऐसा है, तो वह वर्ग probab है अपने MyDropDownList और MyCheckBox कक्षाओं का एक सही और तार्किक सदस्य ly। जिसका अर्थ है कि आप myDropDownListInstance.SharedAttributesClassName.A सिंटैक्स का उपयोग कर रहे हैं। यह दोनों अधिक स्पष्ट और अधिक ईमानदार है। आपके कोड में अनावश्यकता को कम करने के प्रयास के लिए

+0

यह संरचना है, http://en.wikipedia.org/wiki/Composition_over_inheritance – Arjang

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