2009-02-15 19 views
6

Tengo una clase Server que habla con una conexión de servidor para IRC. Tiene una lista de conocidos User s, y los crea según sea necesario.Hacer que los métodos/propiedades sean visibles para una clase, ocultos para otros

Tengo dos problemas que afectan a la clase User:

  1. cualquiera puede crear una instancia de un User. Solo quiero que la clase Server pueda hacer esto.
  2. Si un usuario (lo que User describe) cambia su nombre (u otra información, como canales unidos), la clase Server puede cambiarlo por sí mismo. Sin embargo, ¡otras clases también pueden! Quiero rechazar que otras clases toquen esta información (haciéndola de solo lectura para ellos).

¿Cómo puedo resolver estos dos problemas? En C++, se puede resolver utilizando la palabra clave friend y haciendo que ctor y setName (y tal) sean privados.

¿Hay una palabra clave C# que pueda permitir que cierto método sea accesible por una clase especificada? Esto resolvería mi problema.

Respuesta

8

Honestamente, encuentro que el acceso friend que se originó en C++ es sintomático de un mal diseño. Será mejor que arregles tu diseño.

Para empezar, ¿a quién le importa realmente si alguien crea un Usuario? ¿Realmente importa? Lo pregunto porque parece que a veces los programadores nos preocupamos por cosas que simplemente no sucederán o, si lo hacen, no importa.

Si realmente se preocupan continuación, realice una de las siguientes opciones:

  • Hacer una interfaz de usuario. El servidor puede instanciar una clase privada que lo implementa; o
  • Haga del usuario una clase interna de servidor sin constructores públicos para que solo el servidor pueda instanciarlo.

Los hacks de visibilidad (de los cuales los amigos en C++ son uno y el acceso a los paquetes en Java son buenos ejemplos) simplemente están pidiendo problemas y no son una buena idea.

+0

Fui con los dos métodos que sugirió. Creé una interfaz IUser y una clase interna ServerUser. (También dividí el Servidor en dos clases para que otros puedan escribir sus clientes IRC personalizados.) ¡Gracias por su respuesta! – strager

5

Lo más cercano en el mundo .NET al friend es la visibilidad internal.

Tenga en cuenta que si sus dos clases están en ensamblajes separados, puede usar el atributo InternalsVisibleTo para permitir una visibilidad de conjunto de las partes internas de la otra.

1

Rediseñar su jerarquía de clases es probablemente una solución justa a este problema. Porque me parece que lo que realmente necesitas es una clase de Usuario de solo lectura cuando existe fuera de la clase Servidor.

que probablemente hacer algo como esto:

// An abstract base class. This is what I'd use outside the 
// Server class. It's abstract, so it can't be instantiated 
// on its own, and it only has getters for the properties. 
public abstract class User 
{ 
    protected User() 
    { 
    } 

    public string Name { get;} 
    // Other get-only properties 
} 

public class ServerUser : User 
{ 
    public ServerUser() 
    { 
    } 

    public string Name { get; set;} 
    // Other properties. 
} 

luego hacer que las clases ServerUser creados clase de servidor, el usuario de la clase Server para cambiar las propiedades de las clases ServerUser (como cambiar nombre de usuario), pero sólo exponer las clases de usuario a el mundo exterior.

Cuestiones relacionadas