Skrytí zděděné členy

hlasů
34

Hledám nějaký způsob, jak účinně skrývat zděděných členů. Mám knihovnu tříd, které dědí z běžných základních tříd. Některé z novějších potomků tříd dědit vlastnosti závislostí, které se staly zakrnělé a může být trochu matoucí při používání IntelliSense nebo pomocí tříd ve vizuálním návrhářem.

Tyto třídy jsou všechny ovládací prvky, které jsou psány se sestavují za každé WPF nebo Silverlight 2.0. Vím o ICustomTypeDescriptora ICustomPropertyProvider, ale jsem si docela jistý, ty nelze použít Silverlight.

Není to tolik funkční záležitost jako problém použitelnosti. Co bych měl dělat?

Aktualizace

Některé z vlastností, které bych opravdu chtěla schovat pocházejí z předků, které nejsou moje a protože konkrétní nástroj Jsem navrhování pro nemohu dělat člen skrývá s newoperátorem. (Já vím, že je to směšné)

Položena 04/08/2008 v 20:13
zdroj uživatelem
V jiných jazycích...                            


8 odpovědí

hlasů
32

Přepsat je jako Michael navrhuje výše a zabránit lidi od používání přepsána metody, označit jako zastaralý (sp?):

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

Je-li druhý parm nastavena na hodnotu true, bude chyba kompilátoru být generována, pokud se někdo pokusí volat tuto metodu a řetězec v prvním PARM je poselství. Pokud parm2 je false bude generován pouze varováním kompilátor.

Odpovězeno 04/08/2008 v 21:14
zdroj uživatelem

hlasů
16

I když nemůžete zabránit používání těchto zděděných členů Pokud je mi známo, měli byste být schopni se schovat před IntelliSense pomocí EditorBrowsableAttribute :

Using System.ComponentModel;

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

Edit: Jen to viděl v dokumentaci připomínek, což je docela k ničemu pro tento účel:

Tam je prominentní na vědomí, že se uvádí, že tento atribut „nepotlačuje členů ze třídy ve stejné sestavě.“ To je pravda, ale není dokončena. Ve skutečnosti atribut nepotlačuje členů ze třídy ve stejném roztoku.

Odpovězeno 04/08/2008 v 20:19
zdroj uživatelem

hlasů
13

Jedním z možných věc, kterou můžete udělat, je obsahovat objekt, nikoli vyčnívají z druhé třídy. To vám dá větší flexibilitu, pokud jde o odhalení co chcete vystavit, ale pokud nezbytně potřebují objekt být takového typu, že není ideálním řešením (jakkoli může vystavit objekt z kariérista).

Tím pádem:

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

se stává:

public class MyClass
{
    private BaseClass baseClass;

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

Nebo:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
Odpovězeno 04/08/2008 v 20:22
zdroj uživatelem

hlasů
8

Myslím, že jste nejlepší nejméně hackish způsob, jak je vzít v úvahu složení, na rozdíl od dědické.

Nebo byste mohli vytvářet rozhraní, jehož členy, které chcete mít vaše odvozené třídy implementovat toto rozhraní, a program proti rozhraní.

Odpovězeno 04/08/2008 v 20:19
zdroj uživatelem

hlasů
3

Chcete-li zcela skrýt a označte nepoužívat, včetně IntelliSense, která je podle mého názoru to, co většina čtenářů očekávat ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Odpovězeno 24/06/2013 v 20:50
zdroj uživatelem

hlasů
3

Vím, že tam bylo několik odpovědí na to, a to je teď docela starý, ale nejjednodušší způsob, jak to udělat, je jen deklarovat jako new private.

Vezměme si příklad jsem v současné době pracuje na, kde mám API, které dává k dispozici každou metodu párty DLL 3.. Musím to vzít své metody, ale chci použít vlastnost .Net, namísto „getThisValue“ a metoda „setThisValue“. Tak jsem stavět druhou třídu, zdědí první, aby se majetek, který používá Získání a nastavení metod, a pak přepsat původní Získání a nastavení metod jako soukromé. Jsou stále na každého, kdo chce stavět něco jiného na nich k dispozici, ale jen chci, pokud použít motor Stavím, pak budou moci využívat vlastností namísto metod.

Za použití metody dvojí třídy zbaví jakýchkoliv omezení na tom, že nelze použít newdeklaraci skrýt členy. Vy prostě nelze použít overridev případě, že členové jsou označeny jako virtuální.

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

Nyní valueEnum je obě třídy k dispozici, ale pouze vlastnost je vidět ve třídě APIUsageClass. Třída APIClass je stále k dispozici pro lidi, kteří si chtějí rozšířit původní API nebo ji použít jiným způsobem, a APIUsageClass je k dispozici pro ty, kteří chtějí něco jednoduchého.

V konečném důsledku to, co budu dělat, je dělat APIClass internal a pouze vystavit svou dědičnou třídu.

Odpovězeno 08/12/2010 v 21:54
zdroj uživatelem

hlasů
1

Testoval jsem všechny z navrhovaných řešení a nejsou ve skutečnosti skrývat nové členy.

Ale tento člověk dělá:

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

Ale v code-behide je stále přístupný, takže přidejte i Zastaralé atribut

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
Odpovězeno 23/05/2012 v 11:19
zdroj uživatelem

hlasů
0

Můžete použít rozhraní

    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();
        }
    }
Odpovězeno 13/11/2017 v 00:24
zdroj uživatelem

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