¿Cuál es el caso de uso para el modificador (C# 7.2) "private protected"?


C # 7.2 introduce el modificador protegido privado .

Siempre he protegido el acceso a los campos con propiedades, permitiendo el acceso a través de los métodos Get/Set, ya que normalmente no quiero que el estado interno de mi objeto sea modificado por otra cosa que no sea mi propia clase.

Estoy tratando de entender por qué el equipo del lenguaje C# ha añadido esta característica. Después de una extensa búsqueda en Google, y leer y ver los medios de comunicación 'novedades' (he visto el comunicado de prensa , detalles y video de Mads Torgerson), todavía no soy el más sabio.

Para mí, esto parece permitir a un desarrollador romper el principio de Sustitución de Liskov, pero esto puede ser porque no entiendo por qué esta característica existe ahora.

Entiendo cómo se puede usar, pero no por qué - por favor, ¿puede alguien proporcionar un ejemplo de uso del mundo real en lugar del artificial en los documentos de MSDN?

Author: vaxquis, 2017-11-22

3 answers

Antes de C# 7.2 teníamos protected internal modificador. Esto realmente significa protegido O interno, es decir-member A es accesible para las clases secundarias y también para cualquier clase en el ensamblado actual, incluso si esa clase no es hija de la clase A (por lo que la restricción implícita por "protegido" es relajada).

private protected realmente significa protegido E interno. Que es-miembro es accesible solo a las clases secundarias que están en la misma asamblea, pero no a las clases secundarias que están fuera de la asamblea (por lo que la restricción implied by "protected" is narrowed - becomes even more restrictive). Esto es útil si construye una jerarquía de clases en su ensamblado y no desea que ninguna clase hija de otros ensamblados acceda a ciertas partes de esa jerarquía.

Podemos tomar el ejemplo que Jon Skeet proporcionó en los comentarios. Supongamos que tiene clase

public class MyClass {

}

Y desea ser capaz de heredar de ella solo en el ensamblado actual, pero no desea permitir crear instancias de esta clase directamente excepto dentro de esta jerarquía de clases.

Heredar solo dentro del ensamblaje actual se puede lograr con el constructor interno

public class MyClass {
    internal MyClass() {
    }
}

La prevención de la instanciación directa excepto con la jerarquía de clases actual se puede lograr con el constructor protegido:

public class MyClass {
    protected MyClass() {
    }
}

Y para obtener ambos-necesitas private protected constructor:

public class MyClass {
    private protected MyClass() {
    }
}
 51
Author: Evk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-29 09:17:57

Supongamos que tiene una clase interna llamada SomeHelper que desea usar como parte de la implementación de una clase base abstracta pública:

public abstract class Test
{
    // Won't compile because SomeHelper is internal.
    protected SomeHelper CreateHelper()
    {
        return new SomeHelper();
    }

    public int Func(int x)
    {
        var helper = CreateHelper();
        return helper.DoSomething(x);
    }
}

internal class SomeHelper
{
    public virtual int DoSomething(int x)
    {
        return -x;
    }
}

Esto no se compilará porque no puede tener un método protegido que devuelva un tipo interno. Su único recurso es no usar SomeHelper de esa manera, o hacer SomeHelper público.

(Se podría hacer SomeHelper una clase interna protegida de Test, pero eso no va a funcionar si SomeHelper está destinado a ser utilizado por otras clases que no derive de la clase base.)

Con la introducción de la característica private protected, puede declarar CreateHelper() así:

private protected SomeHelper CreateHelper()
{
    return new SomeHelper();
}

Ahora se compilará, y no tienes que exponer tus componentes internos.

 8
Author: Matthew Watson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-22 09:28:33

Para modificadores de acceso de dos palabras Tengo este concepto. El primer accesor está relacionado con otro ensamblaje, el segundo con ese ensamblaje en el que se definió.

Interno Protegido

  • protegido en otro ensamblado: accesible solo en las clases secundarias.

  • interno en la asamblea actual: accesible para todos en la asamblea actual.

Privado protegido

  • privado en otro ensamblado: no es accesible.
  • protegido en el ensamblado actual: accesible solo en las clases secundarias.
 4
Author: Suren Srapyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-09 09:46:59