سؤال

أنا أبحث عن طريقة لإخفاء فعليا ورثت أعضاء.لدي مكتبة الفئات التي ترث من قاعدة مشتركة الطبقات.بعض من أكثر حداثة سليل الطبقات ترث خصائص التبعية التي أصبحت رمزي و يمكن أن يكون مربكا قليلا عند استخدام التحسس الذكي أو استخدام الطبقات في مصمم البصرية.

هذه الفئات هي كل الضوابط التي كتبت سيتم تجميعها إما WPF أو Silverlight 2.0.أنا أعرف عن ICustomTypeDescriptor و ICustomPropertyProvider, ولكن أنا متأكد من هؤلاء لا يمكن أن تستخدم في سيلفرلايت.

انها ليست الكثير من المشكلات الوظيفية مثل مشكلة الاستخدام.ماذا يجب أن أفعل ؟

التحديث

بعض من الخصائص التي أود حقا أن إخفاء تأتي من الأجداد التي ليست بلدي وبسبب أداة معينة أنا تصميم, لا أستطيع فعل الأعضاء يختبئ مع new المشغل.(أعرف أنها سخيفة)

هل كانت مفيدة؟

المحلول

تجاوز لهم مثل مايكل يوحي أعلاه ومنع الناس من استخدام تجاوزها (sp?) طرق وضع علامة عليها كما عفا عليها الزمن:

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

إذا كان الثاني بارما هو صحيح خطأ التحويل سيتم إنشاء إذا كان أي شخص يحاول استدعاء هذا الأسلوب و السلسلة في أول parm هي الرسالة.إذا parm2 كاذبة فقط مترجم تحذير سيتم إنشاؤها.

نصائح أخرى

في حين لا يمكنك منع استخدام تلك الموروثة أعضاء علمي, يجب أن تكون قادرة على إخفائها من التحسس الذكي باستخدام EditorBrowsableAttribute:

Using System.ComponentModel;

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

تحرير: فقط رأيت هذا في التعليقات الوثائق ، مما يجعل نوعا ما غير مجدية لهذا الغرض:

هناك بارز ملاحظة تنص على أن هذه السمة "لا قمع أعضاء من فئة في نفس الجمعية".هذا صحيح ولكن غير كاملة.في الحقيقة صفة لا قمع أعضاء من فئة في نفس الحل.

واحد محتمل شيء يمكنك القيام به هو تحتوي على الكائن بدلا من تمديد من فئة أخرى.هذا وسوف تعطيك أكثر المرونة في حيث فضح ما تريد فضح, ولكن إذا كنت في حاجة على الإطلاق كائن من هذا النوع ليس الحل المثالي (ومع ذلك يمكن أن تعرض جسم من جالبة).

وبالتالي:

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;
        }
    }
}

أعتقد أنك أفضل على الأقل hackish الطريقة في النظر في تكوين بدلا من الميراث.

أو يمكنك إنشاء واجهة لديها أعضاء تريد ، فئة مشتقة تنفيذ هذه واجهة البرنامج ضد واجهة.

أنا أعلم أنه كان هناك عدة إجابات على هذا, و هو قديم جدا الآن, ولكن أبسط طريقة للقيام بذلك هو مجرد اعلان لهم كما new private.

ينظر على سبيل المثال أنا أعمل حاليا على ، حيث كنت قد API التي تتيح كل طريقة في 3rd الطرف DLL.يجب أن تأخذ الطرق ، ولكن أريد أن استخدام .صافي الممتلكات بدلا من "getThisValue" و "setThisValue" الأسلوب.لذا بناء الدرجة الثانية ترث الأول في عقار يستخدم في الحصول على وتعيين طرق ، ثم تجاوز الأصلي وتعيين طرق خاصة.إنهم لا يزال متاحا للراغبين في بناء شيء مختلف عليها ، ولكن إن كانوا يريدون استخدام محرك أنا المبنى, ثم أنها سوف تكون قادرة على استخدام خصائص بدلا من الأساليب.

استخدام مزدوج الطبقة طريقة يتخلص من أي قيود على كونه غير قادر على استخدام new إعلان إلى إخفاء الأعضاء.كنت ببساطة لا يمكن استخدام override إذا كان أعضاء يتم وضع علامة الظاهري.

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 الدرجة.على APIClass فئة لا تزال متاحة للأشخاص الذين يرغبون في تمديد الأصلي API أو استخدامه بطريقة مختلفة ، APIUsageClass متاحة لأولئك الذين يريدون شيئا أكثر بساطة.

في نهاية المطاف, ما سوف تقوم به هو جعل APIClass الداخلية فقط بفضح ورثت الدرجة.

تماما إخفاء علامة عدم استخدامها ، بما في ذلك التحسس التي أعتقد هو ما معظم القراء يتوقعون ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]

أنا جربت جميع الحلول المقترحة وأنها لا حقا إخفاء الأعضاء الجدد.

ولكن هذا واحد لا:

[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; }
}

يمكنك استخدام واجهة

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

        testList.Add(" this is ok ");

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

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

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

        public static NoRemoveList<T> NewList()
        {
            return new HiddenList();
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top