2010-02-18 2 views
16

मैं इस मामले में इंटरफेस का उपयोग ज्यादातर ऑब्जेक्ट के एक अपरिवर्तनीय उदाहरण के लिए हैंडल के रूप में कर रहा हूं। समस्या यह है कि सी # में नेस्टेड इंटरफेस की अनुमति नहीं है। यहां कोड है:नेस्टेड इंटरफेस के विकल्प (सी # में संभव नहीं)

public interface ICountry 
{ 
    ICountryInfo Info { get; } 

    // Nested interface results in error message: 
    // Error 13 'ICountryInfo': interfaces cannot declare types 
    public interface ICountryInfo 
    { 
     int Population { get; } 
     string Note { get; } 
    } 
} 


public class Country : ICountry 
{ 
    CountryInfo Info { get; set; } 

    public class CountryInfo : ICountry.ICountryInfo 
    { 
     int Population { get; set; } 
     string Note { get; set; } 
     ..... 
    } 
    ..... 
} 

मैं एक विकल्प की तलाश में हूं, किसी को भी समाधान होगा?

+1

क्या कोई विशेष कारण है कि आप 'ICountryInfo' को नेस्टेड करना चाहते हैं? – AakashM

+2

हां, एप्लिकेशन में 100 से अधिक कक्षाएं हैं जिनमें कई नेस्टेड कक्षाएं हैं जो समान नाम हैं। अगर मैं उस सेटअप को बरकरार रखता हूं तो यह बहुत साफ है। इंटरफेस का उपयोग करने के लिए, यह उनके अपरिवर्तनीय समकक्षों का एक तरीका है। एक बार ऑब्जेक्ट्स को तुरंत चालू कर दिया गया है, मुख्य अनुप्रयोग ज्यादातर निर्भरता इंजेक्शन पैटर्न का उपयोग करके अपने संबंधित इंटरफेस से संबंधित है। – ericdes

उत्तर

12

वीबीएनईटी इसकी अनुमति देता है। ,

Public Interface ICountry 
    ReadOnly Property Info() As ICountryInfo 

    Public Interface ICountryInfo 
    ReadOnly Property Population() As Integer 
    ReadOnly Property Note() As String 
    End Interface 
End Interface 

कार्यान्वयन के लिए के रूप में, सी # covariant वापसी प्रकार का समर्थन नहीं करता तो आप इस तरह अपनी कक्षा की घोषणा करनी चाहिए:: तो, आप केवल इंटरफ़ेस परिभाषाओं कि आप की आवश्यकता के साथ एक VB.NET विधानसभा बना सकते हैं

public class Country : ICountry { 
    // this property cannot be declared as CountryInfo 
    public ICountry.ICountryInfo Info { get; set; } 

    public class CountryInfo : ICountry.ICountryInfo { 
    public string Note { get; set; } 
    public int Population { get; set; } 
    } 
} 
2

यह ठीक काम करेंगे, घोंसला करने की कोई जरूरत:

public interface ICountry 
{ 
    ICountryInfo Info { get; } 
} 

public interface ICountryInfo 
{ 
    int Population { get; } 
    string Note { get; } 
} 
+3

हां, लेकिन ... यह कारणों को हराता है कि मैंने नेस्टेड क्लास क्यों बनाया। ICountryInfo का अर्थ किसी अन्य स्थान पर आईकंट्री के मुकाबले नहीं होना चाहिए। – ericdes

+8

मैं @ericdes से सहमत हूं। यह एक ऐसी स्थिति है जहां सी # विफल रहता है। –

2

ICountryInfo ICountry बाहर रहने से कोई कारण नहीं है, तो क्यों नहीं तुम सिर्फ ICountryInfo के गुणों ICountry में डाल दिया और विचार को खारिज कर देना चाहिए नेस्टेड इंटरफेस का?

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

+0

+1 मैं पूरी तरह से सहमत हूं। इस उदाहरण में ICountryInfo रखने की कोई आवश्यकता नहीं है। – Ian

+0

ठीक है, मैंने अभी एक ऐसे एप्लिकेशन से नमूना कोड निकाला है जिसमें 100 से अधिक वर्ग शामिल हैं, जिसमें कई नामांकित वर्ग हैं जो समान नाम हैं। अगर मैं नेस्टेड कक्षाओं के साथ उस सेटअप को बरकरार रखता हूं तो यह बहुत साफ है। इंटरफेस का उपयोग करने के लिए, यह उनके अपरिवर्तनीय समकक्षों का एक तरीका है। एक बार ऑब्जेक्ट्स को तुरंत चालू कर दिया गया है, मुख्य अनुप्रयोग ज्यादातर निर्भरता इंजेक्शन पैटर्न का उपयोग करके अपने संबंधित इंटरफेस से संबंधित है। मैं घोंसले की संरचना को इस तरह से संशोधित नहीं करना चाहता हूं जिसके परिणामस्वरूप अप्रत्याशित कोड होगा। – ericdes

+4

जबकि मैं मानता हूं कि दिया गया उदाहरण वास्तव में समझ में नहीं आता है और एक इंटरफ़ेस के रूप में बेहतर व्यक्त किया जाएगा, इसका मतलब यह नहीं है कि विचार अमान्य है।उदाहरण के लिए यदि आईकंट्री इंटरफ़ेस में केवल एक के बजाय ICountryInfo ऑब्जेक्ट्स का संग्रह था, तो यह स्पष्ट रूप से एक इंटरफ़ेस में इसे फ़्लैट करने के लिए काम नहीं करेगा। ;) – CptRobby

2

यदि अंतिम लक्ष्य निर्भरता इंजेक्शन के साथ इसका उपयोग करना है, तो घोंसले के बजाय उन्हें एक दूसरे में इंजेक्शन देने में क्या गलत है?

public interface ICountry 
{ 
    ICountryInfo Info { get; } 
} 

public interface ICountryInfo 
{ 
    int Population { get; set; } 
    string Note { get; set; } 
} 

और के रूप में लागू: एक बार आप अपने बाइंडिंग की स्थापना जब भी देश इंजेक्ट किया जाता है ICountry & ICountryInfo के लिए, CountryInfo देश में इंजेक्षन जाएगा तब

public class Country : ICountry 
{ 
    private readonly ICountryInfo _countryInfo; 

    public Country(ICountryInfo countryInfo) 
    { 
     _countryInfo = countryInfo; 
    } 

    public ICountryInfo Info 
    { 
     get { return _countryInfo; } 
    } 
} 

public class CountryInfo : ICountryInfo 
{ 
    public int Population { get; set; } 
    public string Note { get; set;} 
} 

यदि आप चाहें तो बाध्यकारी को प्रतिबंधित कर सकते हैं, केवल देश में CountryInfo इंजेक्ट करने के लिए और कहीं और नहीं। निनजेक्ट में उदाहरण:

Bind<ICountry>().To<Country>(); 
Bind<ICountryInfo>().To<CountryInfo>().WhenInjectedInto<Country>(); 
संबंधित मुद्दे