Si j'expose un iEnumerable
iEnumerable
4 Réponses :
Cela dépend de ce que vous retournez. Si vous revenez (disons) une liste Comment vous protégez votre Les données dépendent de ce que vous devez commencer. si vos clients ne bénéficieront pas de la valeur de retour de la valeur de retour ce qui enveloppe efficacement la collection dans un itérateur. (Il existe différentes manières différentes d'utiliser LINQ pour masquer la source ... bien que cela ne soit pas documenté que les opérateurs cachent la source et qui ne le font pas. Par exemple, appeler mutable
Readonlycollection
est un bon emballage classe, en supposant que vous avez un ilist
ilist
Icollection
Skip (0) code> code> < / em> masquer la source dans la mise en œuvre de Microsoft, mais n'est pas documenté pour le faire.) p>
Sélectionnez CODE> définitivement Devrait-il masquer la source. p> p>
Comme d'habitude, Jon Skeet fournit une bonne réponse. J'ai juste besoin d'ajouter que différents types de collecte de données ne sont pas destinés à être utilisés pour la sécurité dans les programmes. Si nous courons dans un environnement de confiance complet, on peut toujours creuser profondément dans nos objets pour trouver tout ce qui est caché à l'intérieur. Nous devons utiliser des mécanismes de sécurité des applications si nous devons vraiment protéger les collections des changements.
La collection peut être renvoyée sur le type d'origine et s'il est mutable, il peut ensuite être muté. P>
Un moyen d'éviter la possibilité que l'original soit muté renvoie une copie em> de la liste. P>
Faire un clone est une solution possible, à droite, mais est-ce vraiment "le meilleur moyen"? Peut-être que parfois c'est, mais parfois pas.
Le retour d'une copie est coûteux pour les grandes collections. Sauf si j'ai vraiment besoin de la sémantique d'une copie, je préfère les emballages comme Jonskeet suggéré.
L'utilisateur peut être capable de renvoyer à la classe de collecte, alors exposez.
collection.Select(x => x)
J'aime ça. Comprenez que si la collection est un type de référence, les éléments des éléments seront toujours mutables, mais changer de cardinalité et de l'ordre de l'encombrement en slurquant dans une liste ou une matrice n'affectera pas la collection d'origine.
Je ne suggérerais pas d'envelopper un itératif dans un itérateur pour empêcher les destinataires de monkeying avec la connexion sous-jacente. Mon inclination serait d'utiliser un wrapper quelque chose comme: si le type de retour des propriétés est L'avantage de la performance d'utilisation d'une structure plutôt que de la classe serait généralement assez légère; Cependant, l'utilisation d'une structure correspondrait à la recommandation générale que les propriétés ne créent pas de nouvelles instances d'objet de tas. Construire une nouvelle instance de struct qui ne contient que une référence à un objet de tas existant est très bon marché. Le plus gros inconvénient d'utiliser une structure telle que définie ici serait qu'il serait verrouillé dans le comportement de la chose renvoyée au code d'appel, alors que simplement renvoyer Notez également que cela peut dans certains cas être possible d'éliminer l'exigence de tout boxe et d'exploiter les optimisations de typage de canard en C # et VB.net ienumerable
enracinable
iEnumerable
enveloppé
var mykeys = mycollection.keys; code>) ou utilise simplement la propriété directement dans une boucle "foreach". Notez que si l'énumérateur renvoyé par
getenumerator () code> serait une structure, qui devra toujours être encadré dans tout cas. P>
ienumerable
foreach code> en boucle si l'on utilise un type comme: P>
public struct FancyWrappedEnumerable<TItems,TEnumerator,TDataSource> : IEnumerable<TItems> where TEnumerator : IEnumerator<TItems>
{
TDataSource _dataSource;
Func<TDataSource,TEnumerator> _convertor;
public FancyWrappedEnumerable(TDataSource dataSource, Func<TDataSource, TEnumerator> convertor)
{
_dataSource = dataSource;
_convertor = convertor;
}
public TEnumerator GetEnumerator()
{
return _convertor(_dataSource);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _convertor(_dataSource);
}
}
Il existe des mises en garde tout en utilisant des collections en tant que propriété, veuillez vérifier ce lien de guide de conception de MSDN docs.microsoft.com/en-us/dotnet/tandard/design-Guidelines/.../a>