¿Hay alguna manera de limitar la creación de instancias de la clase anidada en C#? Quiero evitar la creación de una instancia de clase anidada desde cualquier otra clase, excepto la clase de anidación, pero para permitir el acceso completo a la clase anidada desde otro código.Visibilidad del constructor de clase anidada
Respuesta
Normalmente creo una interfaz para la funcionalidad que desea exponer a otras clases, a continuación, hago que la clase anidada sea privada e implemente esa interfaz. De esta forma, la definición de clase anidada puede permanecer oculta:
public class Outer
{
private class Nested : IFace
{
public Nested(...)
{
}
//interface member implementations...
}
public IFace GetNested()
{
return new Nested();
}
}
En resumen, no, no se puede hacer eso. Hay un modificador de accesibilidad "público" que significa "accesible por cualquier cosa dentro de mí o fuera de mí" y hay un modificador de accesibilidad "privado" que significa "accesible por cualquier cosa dentro de mí". No hay ningún modificador que signifique "accesible para la cosa inmediatamente fuera de mí, pero no para nada que esté fuera de ella", que es lo que necesitaría marcar como constructor. Eso simplemente no es un concepto que los diseñadores del sistema tipo pensaron sería útil.
¿Puedes describir por qué quieres este tipo loco de accesibilidad? Tal vez haya una mejor manera de obtener lo que quieres.
Fuera de mi cabeza (porque me preocupa esto): Implementando IAsyncResult. –
Incorrecto, ver mi respuesta. – MatteoSp
@MatteoSp: Aunque considero encantador que piense que estoy equivocado sobre una característica que implementé, le aseguro que estoy en lo cierto al afirmar que no existe un modificador de accesibilidad que se ajuste a la descripción descrita en el póster original. –
ACTUALIZACIÓN: respuesta incorrecta, ver los comentarios
El modificador interno es lo que busca:
public class OuterClass
{
public class NestedClass {
internal NestedClass()
{
}
}
}
NestedClass serán visibles para todos, pero es constructor estará disponible sólo para OuterClass.
Esta respuesta es incorrecta. Si luego tiene 'clase ThirdClass {void M() {var x = new OuterClass.NestedClass(); }} '. Recuerde, el póster original quería "* Deseo evitar que la clase anidada sea instanciada de cualquier otra clase, excepto la clase de anidamiento. *" Y claramente esto no se ajusta a la factura. –
Sí ... tienes razón. No noté que estaba tratando de invocar el constructor desde un ensamblaje diferente, por eso el modificador interno estaba funcionando ... – MatteoSp
Dado que no hay nada en la sintaxis C#, tendrá que implementar algo así como "un contrato" entre ellos. Se puede aprovechar el hecho de que la clase anidada puede acceder a los campos privados de su matriz:
public class ParentClass
{
private static Func<FriendClass> _friendContract;
public class FriendClass
{
static FriendClass()
{
_friendContract=() => new FriendClass();
}
private FriendClass() { }
}
///Usage
public FriendClass MethodUse()
{
var fInstance = _friendContract();
//fInstance.DoSomething();
return fInstance;
}
}
Por supuesto, se puede ajustar el contrato para manejar diferentes parámetros
private static Func<Arg1,Arg2,FriendClass> _friendContract;
para mí el constructor estático de la clase interna no se llama y obtengo una excepción nullreference –
Si necesita conocer a uno de los siguientes requisitos:
- Usted desea que la clase anidada a sellar,
- usted no quiere copiar todos m de la clase anidada firmas é todo a una interfaz como en Lee's answer,
he encontrado una solución similar a the one posted by ak99372, pero sin utilizar un inicializador estático:
public class Outer
{
private interface IPrivateFactory<T>
{
T CreateInstance();
}
public sealed class Nested
{
private Nested() {
// private constructor, accessible only to the class Factory.
}
public class Factory : IPrivateFactory<Nested>
{
Nested IPrivateFactory<Nested>.CreateInstance() { return new Nested(); }
}
}
public Nested GetNested() {
// We couldn't write these lines outside of the `Outer` class.
IPrivateFactory<Nested> factory = new Nested.Factory();
return factory.CreateInstance();
}
}
La idea es que el constructor de la clase Nested
sólo se puede acceder a la Factory
clase, que está anidado un nivel más profundo. La clase Factory
implementa explícitamente el método CreateInstance
desde la interfaz privada IPrivateFactory
, de modo que solo aquellos que pueden ver IPrivateFactory
pueden llamar al CreateInstance
y obtener una nueva instancia de Nested
.
Código Outer
fuera de la clase no se puede crear libremente los casos de Nested
sin pedir Outer.GetNested()
, porque
Outer.Nested
's constructor se privated, por lo que no se puede llamar directamenteOuter.Nested.Factory
se pueden crear instancias , pero no se puede convertir aIPrivateFactory
, por lo que no se puede llamar al métodoCreateInstance()
.
Tenga en cuenta que no recomendaría utilizar ese patrón en gran medida en el código de producción, pero es un truco que me parece útil tener en la manga en raras ocasiones.
Para la respuesta propuesta por Joshua Smith, me pareció necesario forzar el constructor estático de FriendClass para ejecutarlo, logrando invocar un método vacío de Initalize() en FriendClass desde el constructor estático de ParentClass.
Debería comenta la respuesta de Joshua en lugar de publicar una nueva respuesta que no es realmente una. –
public class Outer
{
public class Nested
{
readonly Outer Outer;
public Nested(Outer outer /* , parameters */)
{
Outer = outer;
// implementation
}
// implementation
}
public Nested GetNested(/* parameters */) => new Nested(this /* , parameters */);
}
Tenga en cuenta que puede acceder a los miembros privados de Outer desde Nested.
- 1. tema visibilidad clase anidada estática con interoperabilidad Scala/Java
- 2. tema visibilidad para constructor de copia de clase base
- 3. Restringir la visibilidad constructor de la clase en Scala 2.9
- 4. Clase anidada con constructor oculto imposible en C#?
- 5. Java clase interna rompecabezas visibilidad
- 6. clase anidada de Javascript
- 7. Clase anidada .GetType()
- 8. Llamando al constructor de clase hijo antes del constructor padre
- 9. ¿Establecer constantes de clase después del constructor?
- 10. Clase anidada: llamada a la clase anidada de la clase principal
- 11. ¿Visibilidad de miembros de la clase?
- 12. C++ - ¿Cómo inicializo un constructor de una clase separada del constructor de una clase?
- 13. Concurrencia, visibilidad del objeto
- 14. Java: ¿visibilidad del subpaquete?
- 15. visibilidad constante de la clase php
- 16. Visibilidad de clase COM: C# a VB6
- 17. clase anidada vs implementos ActionListener
- 18. ¿SwingWorker tiene que ser una clase anidada?
- 19. C++: clase anidada de una clase de plantilla
- 20. Clase anidada dentro de una interfaz
- 21. xaml cuestión de clase anidada diseñador ruta
- 22. Clase de actividad interna anidada en Android
- 23. Mapa de Automapper en clase anidada
- 24. Magento: Obtenga visibilidad del producto
- 25. ¿Puede una clase anidada de C++ heredar su clase adjunta?
- 26. C++ 11 llamar al constructor del constructor del tipo misma clase
- 27. Método de clase base de llamadas del constructor derivado
- 28. C++ Plantilla anidada Clase Método Método
- 29. Resumen Clase Constructor
- 30. C# clase sin constructor
Parece que está reinventando el patrón de diseño Singleton. –
@Bastiaan: te refieres a 'implementar'. No reinventa los patrones de diseño ... – James
Declare los miembros a los que no quiere acceder, incluido el constructor, interno. Es el predeterminado. –