2009-02-15 12 views
6

Ho una classe Server che comunica con una connessione server per IRC. Contiene un elenco di User s noti e li crea se necessario.Rendi metodi/proprietà visibili a una classe, nascosti agli altri

Ho due problemi che coinvolgono la classe User:

  1. Chiunque può creare un'istanza di un User. Voglio solo che la classe Server sia 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, anche altre classi possono! Voglio impedire ad altre classi di toccare queste informazioni (rendendole di sola lettura per 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) privati.

Esiste una parola chiave C# che può consentire ad un determinato metodo di essere accessibile da una classe specificata? Questo risolverebbe il mio problema.

risposta

8

Sinceramente trovo che l'accesso a friend originato da C++ sia sintomatico di una progettazione errata. Stai meglio sistemando il tuo design.

Per cominciare, a chi importa davvero se qualcuno crea un utente? Importa davvero? Lo chiedo perché sembra che a volte i programmatori vengano coinvolti nel 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. Il server può creare un'istanza di una classe privata che la implementa; oppure
  • Rendi Utente una classe interna di Server senza costruttori pubblici, quindi solo il Server può istanziarlo.

Gli hack di visibilità (di cui gli amici in C++ sono uno e l'accesso al pacchetto in Java sono entrambi buoni esempi) richiedono semplicemente problemi e non una buona idea.

+0

Sono andato con entrambi i metodi che hai suggerito. Ho creato un'interfaccia IUser e una classe interna ServerUser. (Ho anche diviso il Server in due classi in modo che altri possano scrivere i loro client IRC personalizzati.) Grazie per la risposta! – strager

5

Il più vicino nel mondo .NET a friend è la visibilità internal.

Nota che se le due classi sono in assemblee separate, è possibile utilizzare l'attributo InternalsVisibleTo per consentire una visibilità assemblaggio delle parti interne degli altri.

1

Ridisegnare la gerarchia delle classi è probabilmente una soluzione equa a questo problema. Perché mi sembra che quello di cui hai veramente bisogno sia una classe User di sola lettura quando esiste al di fuori della classe Server.

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

Poi hanno le classi ServerUser creati Class Server, l'utente la classe di server per modificare le proprietà sulle classi ServerUser (come cambiare nome utente), ma solo esporre le classi utente per il mondo esterno.

Problemi correlati