Ukrywanie dziedziczonych członków

głosy
34

Szukam jakiś sposób, aby skutecznie ukryć odziedziczone członków. Mam biblioteki klas, które dziedziczą z typowych klas bazowych. Niektóre z ostatnich klas potomnych dziedziczyć właściwości zależnościami, które stały się szczątkowa i może być trochę mylące przy użyciu IntelliSense lub przy użyciu klas w visual projektanta.

Klasy te są wszystkie elementy sterujące, które napisane są zestawiane w odniesieniu do obu WPF lub Silverlight 2.0. Znam ICustomTypeDescriptori ICustomPropertyProvider, ale jestem prawie pewien, te nie mogą być używane w Silverlight.

To nie tyle kwestią funkcjonalny jako kwestii użyteczności. Co powinienem zrobić?

Aktualizacja

Niektóre właściwości, które naprawdę chciałbym, aby ukryć się od przodków, które nie są moje własne i z powodu specyficznego narzędzia do projektowania jestem, nie mogę zrobić członek ukrywając z newoperatorem. (Wiem, że to śmieszne)

Utwórz 04/08/2008 o 20:13
źródło użytkownik
W innych językach...                            


8 odpowiedzi

głosy
32

Zastępują je jak Michael proponuje powyżej i zapobiec ludzi od korzystania z nadpisane metody, oznaczyć je jako przestarzałe (sp?):

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

Jeśli drugi z parmezanem jest ustawiony na true, kompilator błąd zostanie wygenerowany, jeśli ktoś próbuje wywołać tę metodę i ciąg w pierwszej parm jest komunikat. Jeśli parm2 jest fałszywa tylko zostanie wygenerowane ostrzeżenie kompilatora.

Odpowiedział 04/08/2008 o 21:14
źródło użytkownik

głosy
16

Chociaż nie można uniknąć wykorzystania tych dziedzicznych członków mojej wiedzy, powinieneś być w stanie ukryć je przed IntelliSense pomocą EditorBrowsableAttribute :

Using System.ComponentModel;

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

Edit: Właśnie widziałem to w komentarzach dokumentacji, co sprawia, że trochę bezużyteczny w tym celu:

Jest wybitnym nuta, która stwierdza, że ​​ten atrybut „nie eliminuje członków z klasy w tym samym zespole.” To prawda, ale nie kompletne. Faktycznie, atrybut nie tłumić członków z klasy w tym samym roztworze.

Odpowiedział 04/08/2008 o 20:19
źródło użytkownik

głosy
13

Jednym z możliwych, co można zrobić, to zawierają obiekt zamiast rozciągać się od drugiej klasy. To daje największą elastyczność w zakresie wystawiania, co chcesz, aby odsłonić, ale jeśli koniecznie musisz być obiekt tego typu nie jest idealnym rozwiązaniem (jednak można wystawiać obiekt z getter).

A zatem:

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

Staje się:

public class MyClass
{
    private BaseClass baseClass;

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

Lub:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
Odpowiedział 04/08/2008 o 20:22
źródło użytkownik

głosy
8

Myślę, że jesteś najlepszym najmniej hackish sposobem jest wzięcie pod uwagę skład w przeciwieństwie do dziedziczenia.

Lub można utworzyć interfejs, który ma członków chcesz, mają swoją klasę pochodną realizacji tego interfejsu i programu przed interfejsu.

Odpowiedział 04/08/2008 o 20:19
źródło użytkownik

głosy
3

Aby w pełni schować i oznaczyć, aby nie używać, w tym intellisense który moim zdaniem jest to, co większość czytelników spodziewać ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Odpowiedział 24/06/2013 o 20:50
źródło użytkownik

głosy
3

Wiem, że minęło kilka odpowiedzi na to, i to dość stary teraz, ale najprostszym sposobem, aby to zrobić jest po prostu zadeklarować je jako new private.

Rozważmy przykład Obecnie pracuję nad, gdzie mam interfejs API, który udostępnia wszelkie metody w 3rd party DLL. Muszę wziąć swoje metody, ale chcę używać właściwość .NET, zamiast „getThisValue” i „setThisValue” metody. Więc budować drugą klasę, dziedziczyć pierwsze, należy właściwość, która korzysta z metod pobierania i ustawiania, a następnie zastąpić oryginalny pobierania i ustawiania metod jako prywatne. Są jeszcze dostępne dla każdego, kto chce zbudować coś innego na nich, ale jeśli po prostu chcesz użyć silnika buduję, to oni będą w stanie wykorzystać właściwości zamiast metod.

Przy wykorzystaniu metody podwójnego klasy pozbywa się wszelkich ograniczeń dotyczących niezdolności do korzystania z newoświadczenia ukryć członków. Po prostu nie można używać override, jeśli członkowie są oznaczone jako wirtualny.

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

Teraz valueEnum jest dostępna dla obu klas, ale tylko obiekt jest widoczny w klasie APIUsageClass. Klasa APIClass jest nadal dostępna dla osób, które chcą rozszerzyć pierwotną API lub wykorzystać go w inny sposób, a APIUsageClass jest dostępna dla tych, którzy chcą coś bardziej prostego.

Ostatecznie, co będę robić to co się APIClass Internal, a jedynie narazić moje dziedziczone klasy.

Odpowiedział 08/12/2010 o 21:54
źródło użytkownik

głosy
1

Przetestowałem wszystkie z proponowanych rozwiązań, a nie naprawdę ukryć nowych członków.

Ale to się robi:

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

Ale w code-behide jest jeszcze dostępne, więc dodać również Przestarzałe Atrybut

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
Odpowiedział 23/05/2012 o 11:19
źródło użytkownik

głosy
0

Można użyć interfejsu

    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();
        }
    }
Odpowiedział 13/11/2017 o 00:24
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more