Domanda

Ho un Server classe che parla con una connessione al server per IRC. Essa detiene un elenco di Users noti, e li crea, se necessario.

Ho due problemi che coinvolgono la classe User:

  1. Chiunque può creare un'istanza di un User. Voglio solo la classe Server di essere in grado di farlo.
  2. Se un utente (la cosa User descrive) cambia la sua / il suo nome (o altre informazioni, come i canali uniti), la classe Server può cambiare se stesso. Tuttavia, altre classi possono, anche! Voglio impedire altre classi di toccare queste informazioni (che lo rende di sola lettura a loro).

Come posso risolvere questi due problemi? In C ++, può essere risolto utilizzando la parola chiave friend e rendendo il ctor e setName (e simili) privato.

C'è un C # parola chiave che può permettere un certo metodo sia accessibile da una classe specifica? Questo sarebbe risolvere il mio problema.

È stato utile?

Soluzione

Onestamente trovo l'accesso friend che ha avuto origine da C ++ per essere il sintomo di cattiva progettazione. È meglio fissare il vostro disegno.

Per cominciare, chi se ne frega se qualcuno crea un utente? Importa davvero? Lo chiedo perché sembra che a volte i programmatori farsi prendere preoccuparsi di cose che semplicemente non accadrà o, se lo fanno, non importa.

Se davvero si cura quindi eseguire una delle seguenti operazioni:

  • Fare uso di un'interfaccia. Server può istanziare una classe privata che lo implementa; o
  • Fare uso di una classe interna Server senza costruttori pubblici in modo che solo Server può creare un'istanza di esso.

hack Visibilità (di cui amici in C ++ sono uno e l'accesso pacchetto in Java sono due buoni esempi) sono semplicemente in cerca di guai e non è una buona idea.

Altri suggerimenti

Il più vicino al mondo .NET per friend è la visibilità internal.

Si noti che se le due classi sono in assemblee separate, è possibile utilizzare il InternalsVisibleTo attributo per consentire visibilità uno assemblaggio delle parti interne degli altri.

La riprogettazione la gerarchia di classe è probabilmente una soluzione equa a questo problema. Perché sembra a me come quello che si ha realmente bisogno è una classe utente di sola lettura quando esiste al di fuori della classe Server.

Vorrei probabilmente fare qualcosa di simile:

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

Sono disponibili le classi ServerUser creati Class Server, utente di classe server per modificare le proprietà sulle classi ServerUser (come cambiare nome utente), ma solo esporre le classi utente al mondo esterno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top