2009-11-24 15 views
26

मेरे पास इंटरफेस का एक सेट है जिसका उपयोग विशेष उत्परिवर्तनीय वस्तु के साथ निकट संयोजन में किया जाता है।सी #: इंटरफ़ेस विरासत प्राप्तकर्ता/सेटर्स

ऑब्जेक्ट के कई उपयोगकर्ताओं को केवल ऑब्जेक्ट से मान पढ़ने की क्षमता और फिर केवल कुछ गुणों की आवश्यकता होती है। नेमस्पेस प्रदूषण (आसान इंटेलिजेंस) से बचने के लिए और उपयोग के इरादे से निपटने के लिए, मैं एक छोटा बेस इंटरफ़ेस रखना चाहता हूं जो केवल पढ़ने के लिए कुछ "कुंजी" गुणों को उजागर करता है।

हालांकि, लगभग सभी कार्यान्वयन पूर्ण इंटरफ़ेस का समर्थन करेंगे, जिसमें संशोधनीयता शामिल है।

दुर्भाग्य से, मैं सी # में है कि अवधारणा व्यक्त रोडब्लॉक में भाग:

interface IBasicProps { 
    public int Priority { get; } 
    public string Name {get;} 
    //... whatever 
} 

interface IBasicPropsWriteable:IBasicProps { 
    public int Priority { set; } //warning CS0108: [...] hides inherited member [...] 
    public string Name { set; } 
    //... whatever 
} 

मैं निश्चित रूप से, किसी भी सदस्य को छिपाने के लिए इच्छुक नहीं किया गया था ताकि नहीं है अच्छा!

बेशक, मैं इसे विधिओं का उपयोग करके हल कर सकता हूं, लेकिन सही विकल्प क्या है? मैं "कोर" इंटरफेस को जितना संभव हो उतना छोटा रखना चाहता हूं भले ही इंटरफेस को विभाजित करना इरादा से अलग करने के अलावा कोई उद्देश्य न करे। विभाजित इंटरफेस के साथ, यह वास्तव में स्पष्ट है कि कौन से तरीके किसी भी अद्यतन करने के लिए नहीं जा रहे हैं, और यह लेखन कोड को थोड़ा स्पष्ट बनाता है (उल्लेख करने के लिए भी कुछ आसान मामलों के लिए पर्याप्त अच्छा-एन-सरल स्थैतिक सिंगलटन स्टब्स की अनुमति नहीं देता है) ।

मैं किसी भी अमूर्त वर्ग और इसी तरह से बचना चाहता हूं; वे सभी जटिल और कठिन-से-ग्रोक के लिए पुन: कार्यान्वयन या त्वरित एकल-उद्देश्य शिम बनाते हैं।

तो, विचार?

उत्तर

27

एक इंटरफ़ेस में छिपाने का तरीका लगभग grungy नहीं है; ,

interface IBasicProps { 
    int Priority { get; } 
    string Name {get;} 
    //... whatever 
} 

interface IBasicPropsWriteable:IBasicProps { 
    new int Priority { get; set; } 
    new string Name { get; set; } 
    //... whatever 
} 
class Foo : IBasicPropsWriteable { 
    public int Priority {get;set;} 
    public string Name {get;set;} 
/* optional 
    int IBasicProps.Priority {get {return Priority;}} 
    string IBasicProps.Name {get {return Name;}} 
*/ 
} 
+0

बोनस के रूप में, यह वास्तव में सह/contravariance के साथ भी अच्छी तरह से काम करता है; मेरा वास्तविक उपयोग मामला 'आईबासिकप्रॉप {/*...*/} की तरह है IasicicPropsWriteable : IBASicProps {} '। यहां इंटरफ़ेस विभाजन आवश्यक है; एक केंद्रीय प्रबंधक एक संग्रह में विभिन्न वस्तुओं को रखने के लिए covariance पसंद करेंगे, लेकिन प्रत्येक वस्तु के व्यक्तिगत मालिकों को पता है कि इसमें किस प्रकार शामिल है। –

+1

व्युत्पन्न इंटरफ़ेस में नई संपत्ति पर गेटटर को छोड़ने के बारे में आप क्या सोचते हैं, जैसा कि यहां बताया गया है? http: // stackoverflow।कॉम/प्रश्न/3516279/इंटरफ़ेस-विरासत-विस्तार-गुण-संभव- टिप्पणी # टिप्पणी 3676924_3516450 –

+0

हालांकि यह शायद सी # में संभवतः कम से कम खराब समाधान संभव है, लेकिन यह अभी भी 'नया' संशोधक का उपयोग करने के लिए असंतोषजनक है क्योंकि इसका मतलब है "वहां एक है एक ही नाम की असंबद्ध संपत्ति, पुरानी संपत्ति अभी भी जीवित है लेकिन 'IBasicPropsWriteable' 'के माध्यम से पहुंचने के लिए एक और जटिल वाक्यविन्यास की आवश्यकता है। यह अच्छा होगा अगर आप अतिरिक्त एक्सेसर के साथ "समान" संपत्ति का विस्तार कर सकें। (एक ही समस्या एक दूसरे को विरासत में प्राप्त करने वाले वर्गों के साथ मौजूद है।) आपके समाधान के साथ, कोड 'स्थैतिक शून्य एम (IBasicPropsWriteable x) {var a = x.Name; var b = ((IBASicProps) x) .नाम; } औपचारिक रूप से दो अलग-अलग सदस्यों को पढ़ता है! –

4

अपने लक्ष्य को यह स्पष्ट जब बनाम लेखन को पढ़ने की अनुमति दी है बनाने के लिए है, तो मैं गुण अलग मनुष्य और सेटर तरीके के बजाय प्रयोग करेंगे: मैं की तरह कुछ के साथ जाना चाहते हैं।

interface IBasicProps { 
    int GetPriority(); 
    string GetName(); 
    //... whatever 
} 

interface IBasicPropsWriteable:IBasicProps { 
    void SetPriority(int priority); 
    void SetName(string name); 
    //... whatever 
} 
+3

यह एक सौंदर्य-प्रतियोगिता विजेता नहीं है, लेकिन ऐसा लगता है कि यह एक बहुत ही सुरक्षित शर्त है, यह ठीक काम करेगा ... –

2

इंटरफ़ेस की विरासत को छोड़ने का एक तरीका हो सकता है। एक केवल पढ़ने के लिए इंटरफ़ेस और एक लिखने केवल-, और आवश्यक के रूप में लागू:

interface IBasicPropsReadable { 
    int Priority { get; } 
    string Name { get; } 
} 

interface IBasicPropsWriteable { 
    int Priority { set; } 
    string Name { set; } 
} 

class SomeClassReadWrite : IBasicPropsReadable, IBasicPropsWriteable { 
    int Priority { get; set; } 
    string Name { get; set; } 
} 

class SomeClassReadOnly : IBasicPropsReadable { 
    int Priority { get; } 
    string Name { get; } 
} 
+2

यह मुझे "एक पढ़ने/लिखने की वस्तु" की सामान्य धारणा व्यक्त नहीं करने देगा। मैं एक विधि कैसे लिख सकता हूं जो अब केवल पढ़ने/लिखने के प्रकार स्वीकार करता है? –

1

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

public interface IBasicProps 
{ 
    int Priority { get; } 
    string Name {get;} 
    //... whatever 
} 

public interface IBasicPropsWriteable 
{ 
    int Priority { get; set; } 
    string Name { get; set; } 
    //... whatever 
} 

public class Foo : IBasicProps, IBasicPropsWriteable 
{ 
    public int Priority { get; set; } 
    public string Name { get; set; } 

    // whatever 
} 

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

public interface IBasicPropsAll : IBasicProps, IBasicPropsWriteable { } 

public class Foo : IBasicPropsAll 
{ 
    public int Priority { get; set; } 
    public string Name { get; set; } 

    // whatever 
} 
+1

आईबासिकप्रॉप सभी दृष्टिकोण काम नहीं करता है (बहुत अच्छी तरह से)। '((IBasicPropsAll) नया फू())। नाम' संदिग्ध है, और संकलक इसे स्वीकार नहीं करेगा। इसका मतलब है कि आपको आमतौर पर डालने की ज़रूरत है। –

+0

हां। आप केवल इंटरफेस टाइप करने के "अनुकूलन" प्राप्त करने के लिए इसका उपयोग करेंगे। मैं इसकी सिफारिश नहीं कर रहा हूं। आप वास्तव में इसका उपयोग नहीं करेंगे, आप अभ्यास में आईबीएसिकप्रॉप या आईबासिकप्रॉप्स को लिखने योग्य होंगे। – tvanfosson

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