Vra

Ek is op soek na 'n manier om effektief te verberg geërf-lede. Ek het 'n biblioteek van klasse wat in besit van gemeenskaplike basis klasse. Sommige van die meer onlangse afstammeling klasse erf afhanklikheid eienskappe wat vestigiale geword en kan 'n bietjie verwarrend wees wanneer die gebruik van IntelliSense of met behulp van die klasse in 'n visuele ontwerper.

Hierdie klasse is al kontroles wat geskryf word saamgestel vir óf WPF of Silver 2.0. Ek weet ICustomTypeDescriptor en ICustomPropertyProvider, maar ek is redelik seker dié kan nie gebruik word in Silver.

Dit is nie so veel 'n funksionele probleem as 'n bruikbaarheid kwessie. Wat moet ek doen?

Update

Van die eienskappe wat ek regtig wil om weg te steek vandaan voorvaders wat nie my eie en as gevolg van 'n spesifieke instrument ek ontwerp vir, kan ek nie lid doen wegkruip met die new operateur. (Ek weet, dit is belaglik)

Was dit nuttig?

Oplossing

ignoreer hulle soos Michael Stel bo en om mense te verhoed dat die gebruik van die geneutraliseer (sp?) Metodes, hou hulle in as uitgediende:

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

As die tweede parm waar gestel, 'n samesteller fout sal gegenereer word as iemand probeer om hierdie metode en die string in die eerste parm noem is die boodskap. As parm2 vals net 'n samesteller waarskuwing sal gegenereer word.

Ander wenke

Terwyl jy nie gebruik van daardie geërf lede om my kennis kan voorkom, moet jy in staat wees om hulle te verberg IntelliSense met behulp van die EditorBrowsableAttribute :

Using System.ComponentModel;

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

Edit: Just sien dit in die dokumentasie kommentaar, wat dit kinda nutteloos vir hierdie doel maak:

  

Daar is 'n prominente nota wat sê dat hierdie kenmerk "nie lede van 'n klas in dieselfde vergadering het onderdruk". Dit is waar, maar nie volledig nie. Eintlik is die kenmerk nie lede onderdruk uit 'n klas in dieselfde oplossing.

Een moontlike ding wat jy kan doen is om die voorwerp bevat eerder as uit te brei van die ander klas. Dit gee jou die meeste buigsaamheid in terme van blootstelling wat jy wil blootstel nie, maar as jy absoluut die voorwerp moet van daardie tipe te wees dit is nie die ideale oplossing (maar jy kan die voorwerp van 'n lucky blootstel).

Dus:

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

Word:

public class MyClass
{
    private BaseClass baseClass;

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

Of:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}

Ek dink jy is die beste minste hackish manier is om die samestelling te oorweeg in teenstelling met erfenis.

Of, kan jy 'n koppelvlak wat die lede wat jy wil het te skep, het jou afgelei klas te implementeer wat koppelvlak, en program teen die koppelvlak.

Ek weet daar is 'n paar antwoorde op hierdie, en dit is nou baie oud, maar die eenvoudigste metode om dit te doen is net verklaar hulle as new private.

Oorweeg 'n voorbeeld Ek is tans besig om op, waar ek 'n API wat beskikbaar elke metode in 'n 3de party DLL maak. Ek moet hulle metodes te neem, maar ek wil 'n Net eiendom te gebruik, in plaas van 'n "getThisValue" en "setThisValue" metode. So, ek bou 'n tweede klas, beërf die eerste, maak 'n eiendom wat die get en stel metodes gebruik, en dan ignoreer die oorspronklike get en stel metodes as private. Hulle is nog beskikbaar vir almal wat wil iets anders op te bou, maar as hulle wil net die enjin ek bou gebruik, dan sal hulle in staat wees om eienskappe te gebruik in plaas van metodes.

Die gebruik van die dubbele klas metode ontslae raak van enige beperkings op nie in staat is om die new verklaring gebruik om die lede weg te steek. Jy kan eenvoudig nie override gebruik as die lede gemerk as virtuele.

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

Nou valueEnum is beskikbaar vir beide klasse, maar net die eiendom is sigbaar in die APIUsageClass klas. Die APIClass klas is nog beskikbaar vir mense wat wil hê dat die oorspronklike API te brei of gebruik dit in 'n ander manier, en die APIUsageClass is beskikbaar vir diegene wat iets meer eenvoudig wil.

Uiteindelik, wat ek sal moet doen is om die APIClass interne en net bloot my geërf klas.

Om ten volle te verberg en Mark te gebruik, insluitend IntelliSense wat ek glo is wat die meeste lesers verwag ...

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

Ek getoets al die voorgestelde oplossings en hulle het nie regtig weg te steek nuwe lede.

Maar hierdie een nie:

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

Maar in kode-behide dit is nog steeds toeganklik, so voeg sowel Uitgediende kenmerk

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

Jy kan 'n koppelvlak om te gebruik

    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();
        }
    }
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top