Skjule arvede medlemmer

stemmer
34

Jeg leter etter en måte å effektivt skjule arvede medlemmer. Jeg har et bibliotek med klasser som arver fra felles grunnklasser. Noen av de nyere kommer klasser arver avhengighet egenskaper som har blitt tilbakedannet og kan være litt forvirrende når du bruker IntelliSense eller bruke klasser i en visuell designer.

Disse klassene er alle kontrollene som er skrevet for å være kompilert for enten WPF eller Silverlight 2.0. Jeg vet om ICustomTypeDescriptorog ICustomPropertyProvider, men jeg er ganske sikker på de kan ikke brukes i Silverlight.

Det er ikke så mye et funksjonelt problem som en brukervennlighet problem. Hva burde jeg gjøre?

Oppdater

Noen av de egenskapene som jeg ville virkelig liker å gjemme komme fra forfedre som ikke er min egen, og på grunn av et bestemt verktøy jeg designer for, jeg kan ikke gjøre medlem skjule med newoperatør. (Jeg vet, det er latterlig)

Publisert på 04/08/2008 klokken 19:13
kilden bruker
På andre språk...                            


8 svar

stemmer
32

Styre dem som Michael Foreslår ovenfor og for å hindre folk fra å bruke overstyrt metoder, merke dem som foreldet (sp?):

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

Dersom andre parm er satt til sann, vil en kompilator feil genereres hvis noen prøver å ringe denne metoden og strengen i første parm er budskapet. Hvis parm2 er falsk bare en kompilator advarsel vil bli generert.

Svarte 04/08/2008 kl. 20:14
kilden bruker

stemmer
16

Selv om du ikke kan forhindre bruk av disse arvede medlemmer til min kunnskap, bør du være i stand til å skjule dem fra IntelliSense bruke EditorBrowsableAttribute :

Using System.ComponentModel;

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

Edit: Bare så dette i dokumentasjons kommentarer, noe som gjør det ganske ubrukelig til dette formålet:

Det er en fremtredende notat som sier at dette attributtet "ikke undertrykke medlemmer fra en klasse i samme forsamlingen". Det er sant, men ikke fullført. Egentlig ikke attributtet ikke undertrykke medlemmer fra en klasse i samme løsning.

Svarte 04/08/2008 kl. 19:19
kilden bruker

stemmer
13

En mulig ting du kan gjøre er å inneholde objektet i stedet strekker seg fra den andre klassen. Dette vil gi deg størst fleksibilitet når det gjelder å utsette hva du ønsker å utsette, men hvis du absolutt må objektet for å være av den typen det er ikke den ideelle løsningen (men du kan utsette objektet fra en getter).

Og dermed:

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

Blir:

public class MyClass
{
    private BaseClass baseClass;

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

Eller:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
Svarte 04/08/2008 kl. 19:22
kilden bruker

stemmer
8

Jeg tror du er best minst hackish måten er å vurdere sammensetningen i motsetning til arv.

Eller du kan lage et grensesnitt som har de medlemmene du vil, ha avledet klasse implementerer dette grensesnittet, og program mot grensesnittet.

Svarte 04/08/2008 kl. 19:19
kilden bruker

stemmer
3

For å fullt ut skjule og merke ikke til å bruke, inkludert IntelliSense som jeg mener er hva de fleste leserne forventer ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Svarte 24/06/2013 kl. 19:50
kilden bruker

stemmer
3

Jeg vet at det har vært flere svar på dette, og det er ganske gammel nå, men den enkleste måten å gjøre dette på er bare å erklære dem som new private.

Vurdere et eksempel Jeg jobber for tiden på, hvor jeg har en API som gjør tilgjengelig hver metode i en tredje part DLL. Jeg må ta sine metoder, men jeg ønsker å bruke en .Net eiendom, i stedet for en "getThisValue" og "setThisValue" metoden. Så, jeg bygge en andre klasse, arver den første, gjøre en eiendom som bruker GET og angi metoder, og deretter overstyre den originale komme og sette metoder som private. De er fortsatt tilgjengelig for alle som ønsker å bygge noe annerledes på dem, men hvis de bare ønsker å bruke motoren jeg bygger, så vil de være i stand til å bruke egenskapene i stedet for metoder.

Ved hjelp av dobbel klassen metoden blir kvitt noen restriksjoner på å være ute av stand til å bruke newerklæringen å skjule medlemmer. Du bare ikke kan bruke overridehvis medlemmene er merket som virtuelle.

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

Nå valueEnum er tilgjengelig for begge klasser, men bare eiendommen er synlig i APIUsageClass klassen. Den APIClass klasse er fortsatt tilgjengelig for folk som ønsker å forlenge den opprinnelige API eller bruke det på en annen måte, og APIUsageClass er tilgjengelig for de som ønsker noe enklere.

Til syvende og sist, hva jeg skal gjøre er å gjøre APIClass internt, og bare utsetter min arvet klasse.

Svarte 08/12/2010 kl. 20:54
kilden bruker

stemmer
1

Jeg testet alle de foreslåtte løsninger og de egentlig ikke skjul nye medlemmer.

Men dette gjør:

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

Men i kode behide er det fortsatt tilgjengelig, så legg også Foreldet Egenskap

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
Svarte 23/05/2012 kl. 10:19
kilden bruker

stemmer
0

Du kan bruke et grensesnitt

    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();
        }
    }
Svarte 13/11/2017 kl. 00:24
kilden bruker

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