Je pense que la façon la plus courante d'ajouter quelque chose à une collection est d'utiliser une sorte de Add
méthode fournie par une collection:
class Item {}
var items = new List<Item>();
items.Add(new Item());
et il n'y a en fait rien d'inhabituel à cela.
Je me demande cependant pourquoi ne le faisons-nous pas de cette façon:
var item = new Item();
item.AddTo(items);
il semble que ce soit plus naturel que la première méthode. Cela aurait l'andvantange que lorsque la Item
classe a une propriété comme Parent
:
class Item
{
public object Parent { get; private set; }
}
vous pouvez rendre le setter privé. Dans ce cas, bien sûr, vous ne pouvez pas utiliser une méthode d'extension.
Mais peut-être que je me trompe et que je n'ai jamais vu ce modèle avant parce que c'est si rare? Savez-vous s'il existe un tel schéma?
Dans C#
une méthode d'extension serait utile pour cela
public static T AddTo(this T item, IList<T> list)
{
list.Add(item);
return item;
}
Et les autres langues? Je suppose que dans la plupart d'entre eux, la Item
classe devait fournir une ICollectionItem
interface appelons cela .
Update-1
J'y ai réfléchi un peu plus et ce modèle serait vraiment utile par exemple si vous ne voulez pas qu'un élément soit ajouté à plusieurs collections.
ICollectable
interface de test :
interface ICollectable<T>
{
// Gets a value indicating whether the item can be in multiple collections.
bool CanBeInMultipleCollections { get; }
// Gets a list of item's owners.
List<ICollection<T>> Owners { get; }
// Adds the item to a collection.
ICollectable<T> AddTo(ICollection<T> collection);
// Removes the item from a collection.
ICollectable<T> RemoveFrom(ICollection<T> collection);
// Checks if the item is in a collection.
bool IsIn(ICollection<T> collection);
}
et un exemple d'implémentation:
class NodeList : List<NodeList>, ICollectable<NodeList>
{
#region ICollectable implementation.
List<ICollection<NodeList>> owners = new List<ICollection<NodeList>>();
public bool CanBeInMultipleCollections
{
get { return false; }
}
public ICollectable<NodeList> AddTo(ICollection<NodeList> collection)
{
if (IsIn(collection))
{
throw new InvalidOperationException("Item already added.");
}
if (!CanBeInMultipleCollections)
{
bool isInAnotherCollection = owners.Count > 0;
if (isInAnotherCollection)
{
throw new InvalidOperationException("Item is already in another collection.");
}
}
collection.Add(this);
owners.Add(collection);
return this;
}
public ICollectable<NodeList> RemoveFrom(ICollection<NodeList> collection)
{
owners.Remove(collection);
collection.Remove(this);
return this;
}
public List<ICollection<NodeList>> Owners
{
get { return owners; }
}
public bool IsIn(ICollection<NodeList> collection)
{
return collection.Contains(this);
}
#endregion
}
usage:
var rootNodeList1 = new NodeList();
var rootNodeList2 = new NodeList();
var subNodeList4 = new NodeList().AddTo(rootNodeList1);
// Let's move it to the other root node:
subNodeList4.RemoveFrom(rootNodeList1).AddTo(rootNodeList2);
// Let's try to add it to the first root node again...
// and it will throw an exception because it can be in only one collection at the same time.
subNodeList4.AddTo(rootNodeList1);
add(item, collection)
, mais ce n'est pas un bon style OO.
item.AddTo(items)
supposons que vous ayez un langage sans méthodes d'extension: naturel ou non, pour prendre en charge addTo, chaque type aurait besoin de cette méthode et la fournirait pour chaque type de collection prenant en charge l'ajout. C'est comme le meilleur exemple d'introduction de dépendances entre tout ce que j'ai jamais entendu: P - Je pense que la fausse prémisse ici est d'essayer de modéliser une abstraction de programmation à la «vraie» vie. Cela tourne souvent mal.