2010-07-02 6 views
3

Je travaille sur un certains projets en C#, et je suis tombé sur le problème suivant:Gestion des données - données Readonly

J'ai certaines classes de type de données, par exemple une classe personne, qui conserve des informations sur une la personne.

En outre, j'ai une classe DataManager, qui est responsable de la gestion des personnes dans mon programme. Si vous souhaitez ajouter, obtenir, rechercher ou supprimer une personne, vous le faites uniquement via la classe DataManager.

Le problème est que je ne veux pas que quelqu'un d'autre que la classe DataManager puisse modifier les objets Person. Si quelqu'un appelle par exemple DataManager.getPerson(int ID), il obtiendrait un objet Personne et serait capable d'utiliser les fonctions de réglage de cet objet Personne pour en modifier le contenu (prénom, nom, identifiant, etc.).

Je veux éviter cela. Je veux seulement que la classe DataManager puisse modifier les objets Person (par des méthodes telles que DataManager.changeFirstNameForPerson(int ID, string name)).

Quelle est la meilleure structure de classe qui peut atteindre cet objectif?

Répondre

2

Eh bien, vous ne serez jamais capable d'empêcher les gens de changer les valeurs à 100%. Ils pourraient toujours passer par la réflexion. Mais, du point de vue de l'API, vous pourriez rendre tous les accesseurs de votre classe Person publics, et tous les setters internes. Tant que les classes Person et DataManager sont dans le même assembly, le DataManager peut accéder correctement aux setters, mais pas les autres applications qui référencent l'assembly.

public class Person 
{ 
    public string Fname { get; internal set; } 
} 


public class DataManager 
{ 
    public void ChangeNameForPerson(int id, string fname) 
    { 
     Person p = Person.GetById(id); 
     // Inside the same assembly. Setter is accessible 
     p.Fname = fname; 
    } 
} 

En dehors de l'assemblée, vous auriez ceci:

Person p = DataManager.GetPerson(1); 
p.Fname = "asdf"; // Compile time error 
DataManager.ChangeNameForPerson(1, "asdf"); // Works fine 
1

Les deux premières choses qui viennent à l'esprit serait:

1 - Faire les setters propriété de personne protégée et ont DataManager dérivent de personne

2 - Faire les setters de propriété personne interne et mettre personne et DataManager dans leur propre assemblage

0

Rend la classe Person immutable; c'est-à-dire, faites tous les champs readonly et ne fournissez que des getters de propriété, pas des setters. Transmettez des valeurs pour tous les champs dans le constructeur.

+0

Je ne sais pas pourquoi cela a voté vers le bas? –

1

Si vous déclarez vos accesseurs get/set dans la classe Person avec le mot clé internal, seuls les objets du même assembly peuvent y accéder. Tant que vous incluez la classe DataManager dans le même assembly, elle aura accès et tout code en dehors de l'assembly ne le sera pas.

-1

Une option consiste à factoriser votre classe Person existante pour être une classe interne de DataManager (c.-à-DataManager.Person), puis créer une nouvelle classe de personne le long des lignes de:

public class Person 
{ 
    private DataManager.Person person; 

    public Person(Datamanager.Person person) 
    { 
     this.person = person 
    } 

    public int ID 
    { 
     get { return person.ID; } 
    } 

    ... 
} 

Ensuite, dans votre DataManager classe, vous feriez quelque chose comme:

public Person GetPerson(int id) 
{ 
    DataManager.Person person = // get the person by ID 
    return new Person(person); 
} 

par code externe a accès à la classe de personne en lecture seule, mais pas moyen d'obtenir une référence à la lecture/écriture DataManager.Person.

Questions connexes