2008-10-15 14 views
18

Como usted ya sabe, modificador de acceso protected internal de .NET Framework funciona de una manera extraña: Esto no significa que la clase está protegida Y interna, que dice que la clase está protegida Ointerno; es decir, se puede acceder a la clase o miembro modificado desde el mismo conjunto y desde la misma jerarquía.¿Cuándo utilizarías el modificador de acceso "protegido interno"?

Entonces, sabiendo esto: ¿Cuándo lo usarías? ¿Puede dar un ejemplo? ¿Existe un buen ejemplo de uso illuminating dentro de .NET Base Class Library?

+0

yo no lo sabía. Siempre pensé que era AND. –

+0

Es lo que imaginas la primera vez que lo lees. Creo que cualquiera podría adivinar de la misma manera. –

+0

Sí, atrapa a todo el mundo la primera vez, creo. –

Respuesta

8

Raramente he necesitado utilizar esta combinación de modificadores de acceso, ya que creo que en todas las circunstancias menos en las más extremas, es un indicador de diseño deficiente. Sin embargo, a veces es necesario tener clases auxiliares, como convertidores de tipo y editores, que accedan al método dentro de su ensamblado, pero solo permitan que las clases derivadas accedan a él en otros casos de uso.

Un ejemplo podría ser una llamada que convierte un tipo en una cadena para el convertidor de tipo. ToString() generalmente no se utiliza para este fin, por lo que es posible que tenga una llamada ToPersistableString() que desee que use el convertidor de tipo, por lo que la convierte en internal. Luego, usted decide que las personas que se derivan de su clase pueden usar esta llamada como parte de su propio esquema de persistencia para su clase derivada, por lo que también la convierte en protected.

.NET Framework Uso
AccessibilityNotifyClients en Control es protected internal. Utilizando Reflector, puedo ver que esto se hizo para que el CheckedItemCollection de CheckListBox pudiera acceder a él cuando cambie los estados marcados.

+0

Esta respuesta es difícil de entender; Realmente no veo lo que hace tu convertidor de tipo o por qué lo está haciendo. En primer lugar, solo funcionará con tipos que tengan 'ToPersistableString()' definido (es decir, prácticamente ninguno). En segundo lugar, ¿por qué convertir el nombre de tipo en una cadena en lugar de usar 'typeof', u obtener el nombre a través de' .GetType(). ToString() '? Y por qué llamarlo 'PersistableString' y no' TypeNameString' - ¿qué es persistente al respecto? Si pudiera aclarar esto y mordir y proporcionar una muestra de código de su convertidor de tipo de ejemplo, revocaré esta respuesta. – Jez

+1

@Jez: es un ejemplo. Simplemente indica que puede tener dos tipos internos (su tipo y su convertidor) que necesitan acceder al método, pero también es posible que desee poder anular ese método para ampliarlo en clases derivadas. Los convertidores de tipo le permiten convertir ay desde diferentes tipos: 'ToPersistableString' proporcionaría una versión de cadena del tipo para permitir que el tipo se mantenga en una cadena. Nadie está convirtiendo el nombre de tipo aquí. Para obtener más información sobre los convertidores de tipo, consulte MSDN (http://msdn.microsoft.com/en-us/library/System.ComponentModel.TypeConverter.aspx) –

2

Lo he usado para métodos internos que quisiera poder usar en un espacio de nombre separado para pruebas de unidad, el espacio de nombre de prueba de unidad contenía una subclase de la clase. que permitió el acceso a los métodos protegidos.

Dicho esto, existe un argumento para hacer que todo sea público para las pruebas unitarias.

+0

¿Quiere decir espacio de nombres o ensamblado? Es posible que desee considerar InternalsVisibleToAttribute para superar el problema de prueba [assembly: InternalsVisibleTo ("Your.Tests")] –

+0

Me refería al espacio de nombres, si tengo que probar una clase con elementos internos, creo un nuevo proyecto pero hago el espacio del nombre lo mismo, así que puedo acceder a ellos. Sé que probablemente no sea la mejor práctica, pero funciona, y las pruebas de unidad no se compilan en mi implementación. Buscaré ese atributo aunque parezca interesante. –

1

Me gustaría añadir un ejemplo de marco ASP.Net MVC:

public abstract class Controller : ControllerBase, <Omitted Interfaces> 
{ 
    protected internal ViewResult View() { 
      return View(null /* viewName */, null /* masterName */, null /* model */); 
     } 

    protected internal ContentResult Content(string content) { 
      return Content(content, null /* contentType */); 
     } 

} 
Cuestiones relacionadas