2009-03-13 12 views
2

Son typique d'exposer les structures de données internes en tant que propriétés à votre classe affaires. Mais lorsque nous devons exposer des structures de type tableau (comme les règles Rule >), nous pourrions rencontrer un problème de mauvaise utilisation (comme dans l'option 1). Il est suggéré d'exposer le clone de telles structures de données en tant que propriétés, de sorte que la structure interne ne soit pas perturbée.Exposer la structure de données de type tableau à l'aide des propriétés

Est-ce que quelqu'un a une solution bien établie pour cela?

public class Rule 
{ 
} 

public class RulesManager 
{ 
    List<Rule> rules = new List<Rule>(); 

    public List<Rule> Rules 
    { 
     get { return rules; } 
     set { rules = value; } 
    } 

    public void Add(Rule r) 
    { 
     rules.Add(r); 
     // Do something else after add; 
    } 

    public void Delete(Rule r) 
    { 
     rules.Remove(r); 
     // Do something else after delete; 
    } 
} 
public class CallingCode 
{ 
    public static void Main() 
    { 
     RulesManager r = new RulesManager(); 
     // Option 1    
     r.Rules.Add(new Rule()); 
     // Option 2 
     r.Add(new Rule()); 
    } 
} 

Répondre

2

au lieu de retourner un Clone, vous pouvez retourner une version en lecture seule de rules en utilisant rules.AsReadOnly().

public IList<Rule> Rules 
{ 
    get { return rules.AsReadOnly(); } 
// set { rules = value; -- should not be allowed to set if read only! 
} 

Notez le IList.

+0

Mais ma définition passera de List à ReadOnlyCollection , rt? – NileshChauhan

+0

Vous avez déjà entendu parler de la coulée de type? :-) Je vais clarifier ... –

0

Au lieu de renvoyer une liste, vous pouvez renvoyer un IEnumerable. Le IEnumerable permet à l'utilisateur de parcourir la collection, mais il ne permet pas à l'utilisateur de le modifier facilement.

Vous pouvez également renvoyer un arryay au lieu d'une liste. Cela va créer une copie de la liste que l'utilisateur ne peut pas facilement modifier.

Enfin, vous devez savoir que l'utilisateur peut également modifier le contenu de la collection. Cela peut être ce que vous voulez, mais vous pouvez également vouloir retourner des copies de vos articles.

0

Je pense qu'il est assez courant d'exposer IList en tant que propriété, mais je préfère n'exposer que des fonctions explicites d'ajout/suppression. Vous pouvez également envisager d'implémenter l'une des interfaces de collection de votre classe (par exemple IList par exemple), si vous développez quelque chose de plus d'un framework.

Au lieu de:

public List<Rule> Rules 
{ 
    get { return rules; } 
    set { rules = value; } 
} 

Je préfère mettre en œuvre IEnumerable<T> et un indexeur de la classe, de sorte que je contrôle sur ce qui se passe à la liste.

0

Une solution de contournement de base consiste à utiliser la méthode List<T>.AsReadOnly(), qui encapsulera la liste autour d'une ReadOnlyCollection pour bloquer tout accès en écriture. Bien sûr, vous devrez rendre le setter privé, sinon cela n'aurait pas de sens ...

Une autre alternative serait d'implémenter votre propre IList qui vous alerterait en cas d'accès "en écriture" et vous permettrait de: effectuez votre logique métier.

Questions connexes