2010-02-13 12 views
7

मैं सी # में इस लक्ष्य को हासिल करना चाहते हैंC# एकाधिक वंशानुक्रम

(स्यूडोकोड)

class A; 

class B : A; 

class C : A, B; 

... 

A ac = (A)c; 

... 

B bc = (B)c; 

यह संभव है?

+0

नहीं, इन्हें जांचें: http://stackoverflow.com/questions/191691/ http://stackoverflow.com/questions/995255/ –

+0

http://stackoverflow.com/questions/2846752/am-i -ट्री-टू-कार्यान्वयन-एकाधिक-विरासत-कैसे-कर-मैं-यह-यह और http://stackoverflow.com/questions/2456154/does-c-support- बहुविध-विरासत – Russell

उत्तर

3

संख्या सी # कक्षाओं के एकाधिक विरासत का समर्थन नहीं करता है।

एक वर्ग एक वर्ग से प्राप्त हो सकता है, और कई इंटरफेस भी कार्यान्वित कर सकता है।

+0

@stakx: अच्छी पकड़। सही किया। –

0

आप एकाधिक विरासत के लिए इंटरफेस का उपयोग कर सकते हैं।

2

सी # में यह संभव नहीं है, लेकिन, आपको यह भी सोचना चाहिए कि यह वह परिदृश्य है जिसे आप वास्तव में चाहते हैं।

वास्तव में एक एक और एक बीसी है? या सी और बी है। यदि उत्तरार्द्ध सत्य है, तो आपको विरासत की बजाय संरचना का उपयोग करना चाहिए।

+0

मैं कुछ कारणों से संरचना का उपयोग नहीं कर सकता। कोशिश की समस्या: बेस क्लास प्रतिनिधियों का उपयोग करते हैं और कॉलबैक में खुद को संदर्भ प्रदान करते हैं। यदि सी में ए और बी शामिल हैं तो कॉलबैक में ए और/या बी के संदर्भ होते हैं, सी आवश्यक नहीं है। यह सुनिश्चित किया जाता है कि अगर मैं ए और बी से सी प्राप्त करता हूं तो इंटरफेस एक विकल्प है, इसे पहले से उपयोग करें। – neil

9

आप इस विशेष मामले में एकाधिक वंशानुक्रम की जरूरत नहीं है: दोनों BऔरA वर्ग CB से केवल विरासत हैं, वर्ग C के किसी भी मामले को डाली जा सकता है; के बाद से पहले से ही BA से निकला है, C फिर A से प्राप्त किया जा की जरूरत नहीं है:

class A  { ... } 

class B : A { ... } 

class C : B { ... } 

... 

C c = new C(); 
B bc = (B)c; // <-- will work just fine without multiple inheritance 
A ac = (A)c; // <-- ditto 

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

+0

Arggh ... मैंने स्पष्ट पर्यवेक्षण किया है। संकेत के लिए धन्यवाद! सम्मान – neil

+0

हम्म। एक समस्या बनी हुई है: मैं सी को ए के रूप में व्यवहार करने के लिए मजबूर नहीं कर सकता ए बी बढ़ाता है और अब सादे एक कार्यक्षमता प्रदान नहीं करता है (आवश्यकतानुसार)। बस बोली जाने वाली मुझे एक सी की आवश्यकता है, जो कभी-कभी संदर्भ के आधार पर ए और कभी-कभी बी के रूप में व्यवहार करता है। – neil

+0

'सी 'को' ए' की तरह व्यवहार करना चाहिए यदि आप इसे 'एसी' के माध्यम से एक्सेस करते हैं; इसी प्रकार, 'सी' को 'बी' के रूप में व्यवहार करना चाहिए यदि आप इसे 'बीसी' के माध्यम से एक्सेस करते हैं। बेशक, यदि आपके पास वर्चुअल विधियां हैं, तो इन सभी मामलों में ओवरराइड संस्करणों को बुलाया जाएगा। – stakx

0

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

इस के आसपास पाने के लिए (भले ही यह लगभग never needed है) मैं partial classes और T4 Text Templates के संयोजन का उपयोग करके एक अनुरूपित एकाधिक विरासत दृष्टिकोण के साथ आया हूं। यह एक मामूली हैक है लेकिन यह व्युत्पन्न कक्षाओं में एक ही इंटरफ़ेस कार्यान्वयन की प्रतिलिपि/चिपकाने से बेहतर है। नीचे एक सरल उदाहरण है:

IInterface.cs

public interface IInterface 
{ 
    void Foo(); 
} 

InterfaceImpl.cs

public partial class InterfaceImpl : IInterface 
{ 
    public void Foo() 
    { 
     Console.WriteLine("Foo"); 
    } 
} 

BaseClass.cs

using System; 

public class BaseClass 
{ 
    public void Bar() 
    { 
     Console.WriteLine("Bar"); 
    } 
} 

DerivedClassA.cs

public partial class DerivedClassA : BaseClass, IInterface 
{ 
    public void FooBar() 
    { 
     this.Foo(); 
     this.Bar(); 
    } 
} 

DerivedClassAInterfaceImpl।टीटी

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassA"); #> 
<#= codeText #> 

DerivedClassB.cs

public partial class DerivedClassB : BaseClass, IInterface 
    { 
     public void BarFoo() 
     { 
      this.Bar(); 
      this.Foo(); 
     } 
    } 

DerivedClassBInterfaceImpl.tt

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassB"); #> 
<#= codeText #> 

यह थोड़ा कष्टप्रद है कि इस प्रत्येक व्युत्पन्न वर्ग इंटरफेस कार्यान्वयन का उपयोग करना चाहता है कि के लिए एक टीटी फ़ाइल बनाने की आवश्यकता है है , लेकिन यह अभी भी कॉपी/पेस्ट कोड पर बचाता है यदि InterfaceImpl.cs कोड की कुछ पंक्तियों से अधिक है। यह संभवतः एक टीटी फ़ाइल बनाने और सभी व्युत्पन्न आंशिक कक्षाओं का नाम निर्दिष्ट करना और multiple files उत्पन्न करना संभव है।

मैंने इस दृष्टिकोण का एक समान प्रश्न here में उल्लेख किया है।

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