2012-02-16 8 views
5

मैं निम्नलिखित कोड हैसार वर्ग, कोड डुप्लिकेशन से कैसे बचें?

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public abstract void Invoke(string message); 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     Time = DateTime.Now; 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     Time = DateTime.Now; 
     // Do B 
    } 
} 

मैं इन Suba और SubB वर्ग है जो आधार वर्ग से विरासत है, तो आप देख सकते हैं मैं एक कोड है कि यह स्वयं जो समय सेट कर रहा है दोहरा है, वहाँ के लिए एक रास्ता है समय की सेटिंग को बेस क्लास में ले जाएं?

उत्तर

3

वहां कई संभावित समाधान हैं।

यह इस संपत्ति पर सेट होने पर निर्भर करता है।

यदि आप इसे तुरंत चाहते हैं तो आप इसे अपने Base कक्षा के निर्माता में कर सकते हैं।

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public virtual void Invoke(string message) { 
     Time = DateTime.Now; 
    } 
} 

internal class SubA : Base 
{ 
} 

internal class SubB : Base 
{ 
} 

तुम अब भी उपवर्गों जहां आप एक अलग कार्यान्वयन चाहते में विधि ओवरराइड कर सकते हैं:

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public abstract void Invoke(string message); 

    public Base() 
    { 
     Time = DateTime.Now; 
    } 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     // Do B 
    } 
} 
+0

इस मामले में SetTime संरक्षित किया जाना चाहिए। – PVitt

2

एक आभासी विधि के बजाय का उपयोग करें।

5

आप कुछ इस तरह कर सकता है:

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public void Invoke(string message){ 
     Time = DateTime.Now; 
     this.InvokeInternal(message); 
    } 
    protected abstract void InvokeInternal(string message); 
} 

internal class SubA : Base 
{ 
    protected override void InvokeInternal(string message) 
    { 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    protected override void InvokeInternal(string message) 
    { 
     // Do B 
    } 
} 
+1

+1। वास्तव में मैं क्या करूँगा। – Jehof

2
internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public virtual void Invoke(string message) 
    { 
     Time = DateTime.Now; 
    } 

} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do B 
    } 
} 
+0

आधार संदर्भ जांचें: http://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx –

0

पहले से ही जवाब के बहुत सारे हैं। एक विकल्प (और निंजा का थोड़ा सा दृष्टिकोण) के रूप में, मैं विधि गुणों के साथ उपयोग किए गए Lambda अभिव्यक्तियों का सुझाव दूंगा।

आपके मामले में;

public class Base 
    { 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public Action<string> Invoke { get; set; } 

    public Base() 
    { 
     this.Invoke = InvokeDefault; 
    } 

    private void InvokeDefault(string message) 
    { 
     Time = DateTime.Now; 
    } 
    } 

इस तरह, हम base कक्षा में डिफ़ॉल्ट व्यवहार प्रदान करते हैं। लैम्ब्डा भाव के साथ आप .. इस प्रकार विभिन्न Invoke तरीकों के साथ उदाहरण बना सकते हैं

var myInstance= new Base 
    { 
    Invoke =() => { Time = DateTime.Now.AddDays(7); } 
    }; 

आह्वान विधि केवल Base वर्ग के इस उदाहरण के लिए ओवरराइड की गई है। यह अधिक लचीलापन देता है और अनावश्यक उपclassing से बचने में मदद करता है।

विवरण के लिए यह awesome post from Patrick Steele देखें।

0

आपके व्यावहारिक विकल्प कितने कठोर हैं, इस पर निर्भर करते हुए दो व्यावहारिक विकल्प हैं।

आप तर्क को वर्चुअल विधि में ले जा सकते हैं और यदि बच्चे चुनते हैं तो बच्चे के व्यवहार को व्यवहार को अधिभारित करने की अनुमति दें।

internal abstract class Base 
{ 
    ... 
    public virtual void Invoke(string message) 
    { 
     Time = DateTime.Now; 
    } 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do B 
    } 
} 

हालांकि यह मूल विधि को कॉल करने के लिए व्युत्पन्न प्रकारों के लिए संभव बनाता है।

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

internal abstract class Base 
{ 
    ... 
    public void Invoke(string message) 
    { 
     Time = DateTime.Now; 
     this.InvokeCore(message); 
    } 

    protected abstract void InvokeCore(string message); 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void InvokeCore(string message) 
    { 
     // Do B 
    } 
} 
संबंधित मुद्दे