वंचित सदस्यों को छुपाएं

मैं विरासत में सदस्यों को प्रभावी ढंग से छिपाने के लिए कुछ रास्ता ढूंढ रहा हूं। मेरे पास कक्षाओं की एक पुस्तकालय है जो सामान्य आधार वर्गों से प्राप्त होता है। कुछ हालिया वंशज वर्गों में निर्भरता गुणों का उत्तराधिकारी होता है जो वेस्टीगियल बन गए हैं और IntelliSense का उपयोग करते समय या दृश्य डिजाइनर में कक्षाओं का उपयोग करते समय थोड़ा उलझन में हो सकते हैं।

ये कक्षाएं सभी नियंत्रण हैं जिन्हें wpf या Silverlight 2.0 के लिए संकलित करने के लिए लिखा गया है। मुझे ICustomTypeDescriptor और ICustomPropertyProvider के बारे में पता है, लेकिन मुझे यकीन है कि सिल्वरलाइट में इसका उपयोग नहीं किया जा सकता है।

उपयोगिता मुद्दे के रूप में यह एक कार्यात्मक मुद्दा नहीं है। मुझे क्या करना चाहिए?

अपडेट

कुछ गुण जो मैं वास्तव में छिपाना पसंद करूंगा उन पूर्वजों से आते हैं जो मेरे नहीं हैं और एक विशिष्ट उपकरण के कारण मैं डिजाइन कर रहा हूं, मैं new ऑपरेटर के साथ छिपाने वाले सदस्य नहीं कर सकता। (मुझे पता है, यह हास्यास्पद है)

0
जोड़ा संपादित
विचारों: 1

8 उत्तर

जबकि आप मेरे ज्ञान के लिए उन विरासत सदस्यों के उपयोग को रोक नहीं सकते हैं, तो आप उन्हें EditorBrowsableAttribute :

Using System.ComponentModel;

[EditorBrowsable(EditorBrowsableState.Never)]
private string MyHiddenString = "Muahahahahahahahaha";

Edit: Just saw this in the documentation comments, which makes it kinda useless for this purpose:

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

0
जोड़ा

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

इस प्रकार:

public class MyClass : BaseClass
{
    // Your stuff here
}

हो जाता है:

public class MyClass
{
    private BaseClass baseClass;

    public void ExposeThisMethod()
    {
        baseClass.ExposeThisMethod();
    }
}

या:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
0
जोड़ा

मुझे लगता है कि आप कम से कम हैकिश तरीका हैं विरासत के विरोध में संरचना पर विचार करना।

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

0
जोड़ा

उनको ओवरराइड करें जैसे माइकल S href="ests ऊपर और लोगों को ओवरराइड (एसपी?) विधियों का उपयोग करने से रोकने के लिए, उन्हें अप्रचलित के रूप में चिह्नित करें:

[Obsolete("These are not supported in this class.", true)]
public override  void dontcallmeanymore()
{
}

यदि दूसरा पार्म सत्य पर सेट किया गया है, तो कोई भी संकलक त्रुटि उत्पन्न की जाएगी यदि कोई उस विधि को कॉल करने का प्रयास करता है और पहले पैरा में स्ट्रिंग संदेश है। अगर पार्म 2 झूठा है तो केवल एक कंपाइलर चेतावनी उत्पन्न की जाएगी।

0
जोड़ा
क्या आप इसे एक ही प्रभाव से भी सील नहीं कर सकते?
जोड़ा लेखक James M, स्रोत
अप्रचलित उपयोग करते समय @RobertPetz, यह एक चेतावनी देता है, त्रुटि नहीं। बड़ा अंतर।
जोड़ा लेखक James M, स्रोत
@RobertPetz आपने स्पष्ट रूप से मेरा नहीं पढ़ा, हालांकि, व्यर्थ कटाक्ष के लिए कुडोस।
जोड़ा लेखक James M, स्रोत
@JamesM सत्य के साथ कोई अप्रचलित सदस्य access को रोकता है, सीलबंद सदस्य विरासत को रोकता है। तो एक मुहरबंद वर्ग से नहीं लिया जा सकता है, और एक मुहरबंद विधि अन्य वर्ग के सदस्यों को ओवरराइड करने की अनुमति देती है लेकिन उस सदस्य को ओवरराइड होने से रोकती है। मुहरबंद उस वर्ग या सदस्य को कॉल करने से नहीं रोकता है, जबकि यदि आप इसे कॉल करने का प्रयास करते हैं तो सत्य के साथ अप्रचलित एक कंपाइलर त्रुटि फेंकता है।
जोड़ा लेखक Robert Petz, स्रोत
@ जेम्सएम उहम ... क्या आपने उस उत्तर को भी पढ़ा था जिसे आपने पहले सचमुच टिप्पणी की थी?
जोड़ा लेखक Robert Petz, स्रोत
@ जेम्सएम लॉल मैंने किया, यही कारण है कि मैंने आपके मूल प्रश्न का उत्तर दिया कि क्यों सीलिंग ने एक ही काम नहीं किया। फिर आपने ध्यान दिया कि Obselete केवल एक चेतावनी देता है, जो गलत है true के दूसरे तर्क के रूप में एक चेतावनी के बजाय एक कंपाइलर त्रुटि का कारण बनता है - जैसा कि आपने सीधे विशेष रूप से टिप्पणी की है राज्यों। अगर मैं आपको गलत समझ रहा हूं, तो मैं स्पष्टीकरण का स्वागत करता हूं। यहां MSDN स्रोत है
जोड़ा लेखक Robert Petz, स्रोत

मुझे पता है कि इसके कई जवाब हैं, और यह अब काफी पुराना है, लेकिन ऐसा करने का सबसे आसान तरीका सिर्फ उन्हें नया निजी के रूप में घोषित करना है।

एक उदाहरण पर विचार करें जो मैं वर्तमान में काम कर रहा हूं, जहां मेरे पास एक एपीआई है जो किसी तृतीय पक्ष डीएलएल में हर विधि उपलब्ध कराती है। मुझे अपनी विधियां लेनी है, लेकिन मैं "getThisValue" और "setThisValue" विधि के बजाय, .Net प्रॉपर्टी का उपयोग करना चाहता हूं। इसलिए, मैं एक दूसरी कक्षा का निर्माण करता हूं, पहले प्राप्त करता हूं, एक ऐसी संपत्ति बनाता हूं जो प्राप्त करने और सेट विधियों का उपयोग करता है, और उसके बाद मूल प्राप्त करें और विधि को निजी रूप से सेट करें। वे अभी भी उन लोगों के लिए उपलब्ध हैं जो किसी पर कुछ अलग करना चाहते हैं, लेकिन अगर वे सिर्फ इंजन का उपयोग करना चाहते हैं, तो वे विधियों के बजाय गुणों का उपयोग करने में सक्षम होंगे।

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

public class APIClass
{
    private static const string DllName = "external.dll";

    [DllImport(DllName)]
    public extern unsafe uint external_setSomething(int x, uint y);

    [DllImport(DllName)]
    public extern unsafe uint external_getSomething(int x, uint* y);

    public enum valueEnum
    {
        On = 0x01000000;
        Off = 0x00000000;
        OnWithOptions = 0x01010000;
        OffWithOptions = 0x00010000;
    }
}

public class APIUsageClass : APIClass
{
    public int Identifier;
    private APIClass m_internalInstance = new APIClass();

    public valueEnum Something
    {
        get
        {
            unsafe
            {
                valueEnum y;
                fixed (valueEnum* yPtr = &y)
                {
                    m_internalInstance.external_getSomething(Identifier, yPtr);
                }
                return y;
            }
        }
        set
        {
            m_internalInstance.external_setSomething(Identifier, value);
        }
    }

    new private uint external_setSomething(int x, float y) { return 0; }
    new private unsafe uint external_getSomething(int x, float* y) { return 0; }
}

अब valueEnum दोनों वर्गों के लिए उपलब्ध है, लेकिन केवल APIUsageClass क्लास में संपत्ति दिखाई दे रही है। एपीआईसीएलएएस क्लास अभी भी उन लोगों के लिए उपलब्ध है जो मूल एपीआई का विस्तार करना चाहते हैं या इसे अलग तरीके से उपयोग करना चाहते हैं, और APIUsageClass उन लोगों के लिए उपलब्ध है जो कुछ और सरल चाहते हैं।

आखिरकार, मैं जो करूँगा वह एपीआईसीएलएएस आंतरिक बना रहा है, और केवल मेरी विरासत कक्षा का पर्दाफाश कर रहा है।

0
जोड़ा
निर्भरता गुणों के लिए इसका उपयोग कैसे किया जाता है?
जोड़ा लेखक James M, स्रोत

मैंने सभी प्रस्तावित समाधानों का परीक्षण किया और वे वास्तव में नए सदस्यों को छिपाते नहीं हैं।

लेकिन यह एक करता है:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}

लेकिन कोड-व्यवहार में यह अभी भी सुलभ है, इसलिए अप्रचलित विशेषता भी जोड़ें

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
0
जोड़ा

उपयोग करने के लिए पूरी तरह छिपाने और चिह्नित करने के लिए, जिसमें इंटेलिजेंस शामिल है, जो मुझे विश्वास है कि अधिकांश पाठक अपेक्षा करते हैं ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
0
जोड़ा

आप एक इंटरफेस का उपयोग कर सकते हैं

    public static void Main()
    {
        NoRemoveList testList = ListFactory.NewList();

        testList.Add(" this is ok ");

        // not ok
        //testList.RemoveAt(0);
    }

    public interface NoRemoveList
    {
        T this[int index] { get; }
        int Count { get; }
        void Add(T item);
    }

    public class ListFactory
    {
        private class HiddenList: List, NoRemoveList
        {
            // no access outside
        }

        public static NoRemoveList NewList()
        {
            return new HiddenList();
        }
    }
0
जोड़ा