Pregunta

Estoy buscando alguna manera de ocultar con eficacia los miembros heredados.Tengo una biblioteca de clases que heredan de la base común de las clases.Algunas de las más recientes las clases descendientes heredan las propiedades de dependencia que se han convertido en vestigial y puede ser un poco confuso cuando se utiliza IntelliSense o el uso de las clases de un diseñador visual.

Estas clases son todos los controles que se escriben para ser compilado para WPF o Silverlight 2.0.Yo sé acerca de ICustomTypeDescriptor y ICustomPropertyProvider, pero estoy bastante seguro de que aquellos que no se pueden usar en Silverlight.

No es tanto funcional de un problema como un problema de usabilidad.¿Qué debo hacer?

Actualización

Algunas de las propiedades que realmente me gustaría ocultar provienen de antepasados que no son de mi propio y debido a una herramienta específica que estoy diseñando para, yo no puedo hacer miembro de ocultar con el new operador.(Lo sé, es ridículo)

¿Fue útil?

Solución

Invalidarla como Sugiere Michael por encima de y para evitar que la gente de la utilización de la anulado (sp?) métodos, marcarlos como obsoleto:

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

Si el segundo parm se establece en true, un compilador de error se genera si alguien trata de llamar a ese método y la cadena en la primera parm es el mensaje.Si parm2 es falsa solo una advertencia del compilador será generado.

Otros consejos

Mientras que usted no puede evitar el uso de aquellos miembros heredados de mi conocimiento, usted debería ser capaz de ocultar de IntelliSense el uso de la EditorBrowsableAttribute:

Using System.ComponentModel;

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

Editar: Acabo de ver esto en los comentarios de documentación, lo que hace que sea un poco inútil para este propósito:

Hay un prominente nota que indica que este atributo de "no reprimir a los miembros de una clase en la misma asamblea".Eso es cierto, pero no completa.En realidad, el atributo no reprimir a los miembros de una clase en la misma solución.

Una cosa que puedes hacer es contener el objeto, en lugar de extender de la clase.Esto le dará más flexibilidad en términos de exponer lo que se desea exponer, pero si es absolutamente necesario que el objeto de ese tipo no es la solución ideal (sin embargo, usted podría exponer el objeto de un captador).

Por lo tanto:

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

Se convierte en:

public class MyClass
{
    private BaseClass baseClass;

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

O:

public class MyClass
{
    private BaseClass baseClass;

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

Creo que es mejor que menos hackish manera es considerar la composición como en la oposición a la herencia.

O, usted podría crear una interfaz que tiene los miembros que desee tener su clase derivada de implementar la interfaz, y el programa en contra de la interfaz.

Sé que ha habido varias respuestas a esta, y es bastante viejo, pero el método más simple de hacer esto es simplemente declarar como new private.

Considere por ejemplo el que estoy trabajando actualmente, donde tengo una API que pone a disposición de cada método en una 3ª parte de DLL.Tengo que tomar sus métodos, pero quiero usar una .Netas de la propiedad, en lugar de un "getThisValue" y "setThisValue" método.Así que, voy a construir una segunda clase, heredar la primera, hacer que una propiedad que utiliza los métodos get y set, y luego reemplazar el original de los métodos get y set como privado.Todavía están disponibles para cualquiera que quiera construir algo diferente en ellos, pero si sólo desea utilizar el motor estoy construyendo, entonces será capaz de utilizar las propiedades en lugar de los métodos.

El uso del doble método de clase se deshace de cualquier restricción de no poder utilizar el new declaración para ocultar los miembros.Usted simplemente no puede usar override si los miembros están marcados como virtual.

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

Ahora valueEnum está disponible para ambas clases, pero sólo la propiedad es visible en la APIUsageClass clase.El APIClass clase todavía está disponible para las personas que quieren extender el original de la API o el uso de una manera diferente, y la APIUsageClass está disponible para aquellos que quieren algo más simple.

En última instancia, lo que voy a hacer es hacer el APIClass interno, y sólo exponer mi clase heredada.

Para ocultar completamente y marca a no utilizar, incluyendo intellisense que creo que es lo que la mayoría de los lectores esperan ...

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

He probado todas las soluciones propuestas, y que en realidad no ocultar a los nuevos miembros.

Pero este NO:

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

Pero en el código-behide es todavía accesible, por lo que añadir, como bien Obsoleto Atributo

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

Usted puede utilizar una interfaz

    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();
        }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top