Pregunta

Tengo un Server clase que habla con una conexión de servidor de IRC. Contiene una lista de Users conocidos, y las crea si es necesario.

Tengo dos problemas que afectan a la clase User:

  1. Cualquier persona puede crear una instancia de un User. Sólo quiero la clase Server para ser capaz de hacer esto.
  2. Si un usuario (lo describe User) cambia su / su nombre (u otra información, como los canales unidas), la clase Server puede cambiar ella misma. Sin embargo, otras clases también puede! Quiero no permitir otras clases de tocar esta información (por lo que es de sólo lectura a ellos).

¿Cómo puedo resolver estos dos problemas? En C ++, se puede resolver mediante el uso de la palabra clave friend y haciendo que el ctor y setName (y tal) privado.

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

¿Fue útil?

Solución

Sinceramente creo que el acceso friend que se originó en C ++ para ser un síntoma de un mal diseño. Es mejor que la fijación de su diseño.

Para empezar, a quién le importa si alguien crea un usuario? ¿Realmente importa? Lo pregunto porque parece que a veces los programadores se ven atrapados preocuparse por las cosas que simplemente no va a pasar o, si lo hacen, no importa.

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

  • Hacer una interfaz de usuario. Servidor puede crear una instancia de una clase privada que lo implementa; o
  • Haga usuario una clase interna del servidor sin constructores públicos por lo que sólo se puede crear una instancia de servidor de la misma.

hacks Visibilidad (de los cuales los amigos en C ++ son uno y acceso a paquetes en Java son dos buenos ejemplos) simplemente están buscando problemas y no es una buena idea.

Otros consejos

Lo más cerca que en el mundo .NET para friend es la visibilidad internal.

Tenga en cuenta que si sus dos clases están en asambleas separadas, se puede utilizar el InternalsVisibleTo atributo para permitir la visibilidad de un montaje de las partes internas de la otra.

El rediseño de su jerarquía de clases es probablemente una solución justa a este problema. Debido a que me suena como lo que realmente necesita es una clase de usuario de sólo lectura cuando existe fuera de la clase de servidor.

Yo 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. 
}

A continuación, tiene las clases ServerUser creados clase de servidor, usuario de la clase del servidor para cambiar las propiedades de las clases ServerUser (como cambiar nombre de usuario), pero sólo exponer Clases de usuario con el mundo exterior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top