J'ai une question sur les "meilleures pratiques" concernant la POO en C # (mais elle s'applique en quelque sorte à tous les langages).
Envisagez d'avoir une classe de bibliothèque avec un objet qui doit être exposé au public, par exemple via un accesseur de propriété, mais nous ne voulons pas que le public (les personnes utilisant cette classe de bibliothèque) le modifie.
class A
{
// Note: List is just example, I am interested in objects in general.
private List<string> _items = new List<string>() { "hello" }
public List<string> Items
{
get
{
// Option A (not read-only), can be modified from outside:
return _items;
// Option B (sort-of read-only):
return new List<string>( _items );
// Option C, must change return type to ReadOnlyCollection<string>
return new ReadOnlyCollection<string>( _items );
}
}
}
Évidemment, la meilleure approche est "l'option C", mais très peu d'objets ont une variante ReadOnly (et certainement aucune classe définie par l'utilisateur ne l'a).
Si vous étiez l’utilisateur de la classe A, vous attendriez-vous à des changements
List<string> someList = ( new A() ).Items;
se propager à l'objet original (A)? Ou est-il correct de renvoyer un clone à condition qu'il ait été écrit ainsi dans les commentaires / documentation? Je pense que cette approche clone pourrait conduire à des bugs assez difficiles à suivre.
Je me souviens qu'en C ++, nous pouvions retourner des objets const et vous ne pouviez appeler que des méthodes marquées comme const dessus. Je suppose qu'il n'y a pas une telle fonctionnalité / modèle dans le C #? Sinon, pourquoi ne l'incluraient-ils pas? Je crois que cela s'appelle la constance.
Mais là encore, ma principale question concerne «à quoi vous attendriez-vous» ou comment gérer l'option A vs B.