2011-03-04 21 views
5

मैं इंटरफेस/सार कक्षाओं की एक श्रृंखला बना रहा हूं जिसमें मूल गुण हैं और मैं गणना गुण और एकाधिक विरासत चाहता हूं।सी #: गैर-सार गणना गुणों के साथ एकाधिक विरासत

public abstract class /interface Modifiable 
{ 
    public DateTime ModifiedDate {get; set;} 

    public boo ModifiedToday 
    { 
    get { return DateTime.Now.AddDays(-1).CompareTo(ModifiedDate) >= 0; } 
    } 

    public bool ModifiedInLastWeek 
    { 
    get { return DateTime.Now.AddDays(-7).CompareTo(ModifiedDate) >= 0; } 
    } 
} 

public abstract class /interface Deletable 
{ 
    public DateTime DeletionDate {get; set;}  

    public bool Deleted 
    { 
    get { return DeletionDate != default(DateTime) } 
    } 
} 

तब मेरे पास एक कक्षा है जो इन दो इंटरफेस/सार कक्षाओं से प्राप्त होती है।

public class Something : Modifiable, Deletable 
{ 
    // 
} 

लेकिन एक वर्ग दो अमूर्त वर्गों से प्राप्त नहीं हो सकता है। इसलिए मुझे इंटरफेस का उपयोग करने की आवश्यकता है, लेकिन इंटरफेस के साथ मेरे पास विधि निकाय नहीं हो सकते हैं। मुझे इंटरफेस का उपयोग करके इन साधारण बूल गुणों को लागू करने के लिए कई कक्षाओं में समान सटीक कार्यों को परिभाषित करना होगा।

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

क्या कोई डिज़ाइन पैटर्न है जो फ़ंक्शन निकायों को अनुमति देकर एक अमूर्त वर्ग की नकल करता है, लेकिन इंटरफ़ेस जैसे एकाधिक उत्तराधिकारी की अनुमति देता है?

+2

यह सीधे संबंधित नहीं है आपके प्रश्न के लिए, लेकिन केवल कुछ टिप्पणियां: 1. आप इसके बजाय 'डेटटाइम?' (शून्य दिनांक दिनांक) का उपयोग करना चाहेंगे, फिर आप 'DeletionDate! = null' कर सकते हैं 'रिटर्न DeletionDate! = डिफ़ॉल्ट (दिनांक समय) '। 2. इंटरफेस के नाम से पहले "मैं" डालने के लिए यह एक सी # सम्मेलन है, इसलिए आप 'IModifiable' और' IDeletable' रखना चाहते हैं। –

उत्तर

1

सं। सी # में इस तरह के एकाधिक विरासत को लागू करने के लिए एक तंत्र नहीं है।

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

कई विरासतों के लिए उपयोग की जाने वाली कक्षाओं का पुन: उपयोग करने के लिए संभावित रूप से संरचना का उपयोग करके एक अलग डिज़ाइन पर विचार करें।

0

क्षमा करें, सी # में एकाधिक विरासत संभव नहीं है और यह आपके लिए एक बमर है। आपके विकल्प हैं:

  1. या तो अपने आधार वर्ग विरासत श्रृंखला के लिए एक ला MyClass: MyBaseClass: EvenBasierClass
  2. या एकाधिक इंटरफेस से विरासत। और सभी इंटरफेस के सभी तरीकों को लागू करें।

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

1

यह एकाधिक विरासत नहीं है, लेकिन कुछ ऐसा जो मन में आता है वह एक्सटेंशन विधियां है।

public interface IModifiable 
{ 
    DateTime ModifiedDate {get; set;} 
} 

public static class ModifiableExtensions 
{ 
    public bool ModifiedToday(this IModifiable m) 
    { 
     return DateTime.Now.AddDays(-1).CompareTo(m.ModifiedDate) >= 0; 
    } 

    public bool ModifiedInLastWeek(this IModifiable m) 
    { 
    return DateTime.Now.AddDays(-7).CompareTo(m.ModifiedDate) >= 0; 
    } 

} 

इससे प्रकार में बेक जाने वाले सहायक तरीकों का "अनुभव" मिलता है, लेकिन उन्हें कहीं और घोषित किया जाता है। इस वर्ग लें:

public class MyModifiable :IModifiable 
{ 
    public ModifiedDate {get; set;} 
} 

और आप ऐसा कर सकते हैं:

MyModifiable m = new MyModifiable; 

m.ModifiedDate = DateTime.Now; 

bool isToday = m.ModifiedToday(); 
+1

-1: स्क्रम मास्टर की पोस्ट के तहत नीचे दी गई मेरी टिप्पणियां देखें। –

0

परिवर्तनीय इंटरफेस & हटाने-योग्य IMO होना चाहिए, आधार वर्ग नहीं। एक बेस क्लास परिभाषित करता है कि एक प्रकार क्या है, जबकि एक इंटरफ़ेस वर्णन करता है कि एक प्रकार क्या करता है।

जहाँ तक कोड को लागू करने के रूप में, आप हमेशा विस्तार तरीकों का उपयोग कर सकते हैं:

public interface IModifiable 
{ 
    public DateTime ModifiedDate {get; set;} 
} 

public interface IDeletable 
{ 
    public DateTime DeletionDate {get; set;}  
} 


public static class SomeExtentions 
{ 
    public static bool IsModifiedToday(this IModifiable modifiable) 
    { 
     return DateTime.Now.AddDays(-1).CompareTo(modifiable.ModifiedDate) >= 0; 
    } 

    public static bool IsModifiedInLastWeek(this IModifiable modifiable) 
    { 
     return DateTime.Now.AddDays(-7).CompareTo(modifiable.ModifiedDate) >= 0; 
    } 
    public static bool IsDeleted(this IDeletable deletable) 
    { 
     return deletable.DeletionDate != default(DateTime); 
    } 
} 
+0

अगर मैंने केवल इसके बारे में सोचा था ... RQDQ

+0

@rqdq मुझे लगता है कि आपने लगभग सटीक * कोड * समाधान पोस्ट किया है, हालांकि मेरे उत्तर की पहली पंक्ति यह है कि मैंने इसे हटाया नहीं है। –

+0

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

0

मैं शायद इस लक्ष्य को हासिल करने के लिए प्रतिनिधिमंडल का प्रयोग करेंगे।इंटरफेस के रूप में संशोधित और हटाने योग्य बनाएं, फिर उन लोगों के कार्यान्वयन बनाएं। इन कार्यान्वयन के Something कक्षा के उदाहरण दें। यहां डिलीटेबल के लिए एक उदाहरण दिया गया है:

public interface Deletable 
{ 
    DateTime DeletionDate{get;set;} 
    bool Deleted{get;} 
} 

public class DeletableImpl : Deletable 
{ 
    public DateTime DeletionDate{get; set;} 
    public bool Deleted{get {return DeletionDate != default(DateTime);}} 
} 
// Do the same thing with Modifiable and ModifiableImpl 

public class Something : Deletable, Modifiable 
{ 
    private Deletable _deletable = new DeletableImpl(); 
    private Modifiable _modifiable = new ModifiableImpl(); 
    public DateTime DeletionDate 
    { 
    get{return _deletable.DeletionDate;} 
    set{_deletable.DeletionDate = value;} 
    } 
    public bool Deleted{get{return _deletable.Deleted;}} 
    public DateTime ModifiedDate { 
    // and so on as above 
} 
1

हां, वास्तव में कई तरीके हैं। कुछ विचार:

  • Deletable, Modifiable आदि (बुलाया मार्कर इंटरफेस) के लिए एक खाली इंटरफ़ेस का उपयोग करें, तो उनके लिए विस्तार तरीकों पैदा करते हैं। यह एकाधिक विरासत के रूप में विस्तार योग्य नहीं है, लेकिन यह एक लंबा रास्ता तय करता है।
  • निर्भरता बनाने के लिए संभवतः एक ही टैगिंग इंटरफेस के साथ सामान्यता का उपयोग करें। इस तरह आप मॉड्यूलिबल और डिलीटेबल दोनों के लिए बेस क्लास प्राप्त कर सकते हैं, जिसमें समेकित कक्षाएं
  • समान परिणाम प्राप्त करने के लिए पहलू उन्मुख प्रोग्रामिंग का उपयोग करें
  • लगभग वही है, लेकिन इसे स्वयं करें कैसल या इसी तरह की लाइब्रेरी के साथ, संभवतः विशेषताओं की सहायता से।

जाहिर है, उपरोक्त में से कोई भी एकाधिक विरासत के सभी फायदे नहीं है। यदि आप .NET में एकाधिक विरासत चाहते हैं, तो आप C++ .NET या Eiffel.NET का उपयोग कर सकते हैं।

1

मैं डिजाइन पैटर्न नाम भूल जाते हैं, लेकिन वहाँ के सदस्यों के इंटरफेस कार्यान्वयन के आसपास विधि/संपत्ति कॉल जो कि एक ही इंटरफ़ेस के हैं लपेटकर द्वारा कई इंटरफेस को लागू करने के एक पैटर्न है:

interface IDrivable { 
    void Drive(); 
} 

interface IFlyable { 
    void Fly(); 
} 

class Car : IDrivable { 
    public void Drive() { /* Implementation */ } 
} 

class Plane : IFlyable { 
    public void Fly() { /* Implementation */ } 
} 

class MyClass : IDrivable, IFlyable { 
    private IDrivable _car = new Car(); 
    private IFlyable _plane = new Plane(); 

    public void Drive() { _car.Drive(); } 
    public void Fly() { _plane.Fly(); } 
} 
संबंधित मुद्दे