6
votes

Est-il possible de supprimer des éléments dans une liste d'une liste sans perdre la référence d'origine?

OK c'est un peu difficile à demander, mais je vais essayer. J'ai une liste avec des objets (lots), qui contient à nouveau une liste avec des objets (Wafers). Lorsque je change une valeur dans une plaquette, elle sera modifiée dans les deux listes! C'est ce que je veux. Mais lorsque je veux supprimer une plaquette de la liste copiée, elle ne doit pas être supprimée de la liste d'orginal. Je souhaite donc avoir une nouvelle liste de plaquettes dans chaque lot, mais les références aux plaquettes doivent être identiques que dans le lot d'origine, car je souhaite modifier les valeurs aux plaquettes et changer les valeurs dans la plaquette orginale et la plaquette copiée. . Est-il possible sans copie profonde?

J'ai le code suivant pour l'expliquer mieux: P>

    public class Lot
    {
        public string LotName { get; set; }

        public List<Wafer> Wafers { get; set; }
    }

    public class Wafer
    {
        public string WaferName { get; set; }

    }
    [Test]
    public void ListInListTest()
    {
                    //Some Testdata

        List<Lot> lotList = new List<Lot>();
        Lot lot = new Lot();
        lot.LotName = "Lot1";
        lot.Wafers = new List<Wafer>();
        Wafer wafer = new Wafer();
        wafer.WaferName = "Wafer1";
        lot.Wafers.Add(wafer);
        wafer = new Wafer();
        wafer.WaferName = "Wafer2";
        lot.Wafers.Add(wafer);
        wafer = new Wafer();
        wafer.WaferName = "Wafer3";
        lot.Wafers.Add(wafer);
        wafer = new Wafer();
        wafer.WaferName = "Wafer4";
        lot.Wafers.Add(wafer);
        lotList.Add(lot);

        lot = new Lot();
        lot.LotName = "Lot1";
        lot.Wafers = new List<Wafer>();
        wafer = new Wafer();
        wafer.WaferName = "Wafer1";
        lot.Wafers.Add(wafer);
        wafer = new Wafer();
        wafer.WaferName = "Wafer2";
        lot.Wafers.Add(wafer);
        wafer = new Wafer();
        wafer.WaferName = "Wafer3";
        lot.Wafers.Add(wafer);
        wafer = new Wafer();
        wafer.WaferName = "Wafer4";
        lot.Wafers.Add(wafer);
        lotList.Add(lot);

         //Copy the List
        List<Lot> copyList = CopyList(lotList);

        //That works. It removes the lot just in the copyList but not in 
        //the original one
        copyList.RemoveAt(1);

        //This works not like i want. It removes the wafers from the copied list
        //and the original list. I just want, that the list will be changed
        //in the copied list
        copyList[0].Wafers.RemoveAt(0);


    }

    private List<Lot> CopyList(List<Lot> lotList)
    {
        List<Lot> result = new List<Lot>(lotList);

        foreach (Lot lot in result)
        {
            lot.Wafers = new List<Wafer>(lot.Wafers);
        }

        return result;
    }


4 commentaires

vous pouvez essayer ce Stackoverflow.com/Questtions/1582285/...


Vous pouvez essayer de sérialiser puis de désérialiser sans une copie profonde


Êtes-vous sûr que cela ne fonctionne pas? Il semble que vous ayez bien, créez une nouvelle liste de plaquettes (c'est important) qui est renseignée par des références existantes. Devrait marcher.


Non tu ne peux pas. Une fois que toutes les références de plaquettes ne sont pas copiées à moins que vous fassiez une copie profonde dans «COPYLIST».


5 Réponses :


0
votes

Le problème est que vous créez la liste clone en maintenant une référence avec la liste principale. Vous devriez utiliser quelque chose comme: xxx


4 commentaires

Aucune nouvelle gaufrette n'est créée, semble-t-il. Seules les références doivent être conservées.


Nope, il n'a pas besoin de la référence à wafers , car comme vous pouvez le constater, il souhaite modifier la liste copiée sans produire d'effet sur la liste principale.


Il ne sert à rien de créer de nouvelles plaquettes s'il suffit de copier la référence.


Je veux avoir les mêmes wafers (même référence). Mais la liste des plaquettes devrait être une nouvelle référence par lot. Donc, la taille de la nappe peut être différente, par exemple .. Donc, lorsque je supprimai une plaquette de la liste copiée, il ne faut pas le supprimer de la liste d'origine. Mais lorsque je modifie une valeur de n'importe quelle plaquette, il devrait également modifier la valeur de la plaquette dans la liste correspondante. Ce que vous avez essayé est une couture de profondeur. Mais je ne veux pas avoir une copie profonde, car je veux modifier des valeurs dans une plaquette une fois pour toutes les gaufres avec la même référence. Oui je sais .. ^^ ... un peu déroutant



0
votes

Réponse courte: oui c'est possible. Cependant, la méthode de la copyliste devrait ressembler à ce xxx

Ceci créera une nouvelle lotlist et ajoutera toutes les plaquettes existantes.


10 commentaires

Mais ça ne marche pas comme je l'ai fait. Lorsque je retire une plaquette de la liste copiée, il l'enlève également de la liste d'origine: (...


Ça ne marche pas. Si vous copiez / collez-la dans une application de console, vous verrez le comportement décrit.


@Jeffrson aussi loin que je peux voir ... ce n'est pas.


Ok - oui. Le problème est que les listes d'origine sont utilisées. Il y a une nouvelle copie des plaquettes, mais pas une nouvelle lotlist. J'ai négligé cela, évidemment. Éditera la réponse.


Voir la nouvelle version de la copyliste


@Jeffrson Cette réponse est toujours fausse, il n'est pas possible d'avoir la même référence ( lot objet) dans deux listes mais avoir 2 références de propriétés ( ). La seule solution consiste à cloner la liste et à conserver les objets de synchronisation à l'aide d'un autre moyen (par exemple le modèle sujets / observateur).


@James: la première ligne de la boucle de la boucle crée une nouvelle liste de lots - alors que voulez-vous dire? C'est une autre liste et elle est ajoutée à la liste copiée (résultat).


@Jefftrson Votre solution récemment proposée fait comme ce que j'ai aussi suggéré dans ma réponse - cependant, vous semblez toujours suggérer que ce que l'OP demande peut être fait, mais en utilisant votre code - qu'il ne peut pas. Lorsque les objets lot sont clonés, la référence de la liste d'origine est perdue afin de mettre à jour un objet lot dans la liste de copie ne sera plus la même chose objet dans la liste d'origine. L'OP veut être capable de conserver l'instance lot sur les deux listes, mais maintenez une propriété distincte wafers par liste qui ne peut pas être effectuée.


À moins que je sache à nouveau, c'est l'inverse. "Donc, je veux avoir une nouvelle liste de plaquettes dans chaque lot, mais les références aux plaquettes devraient être les mêmes que dans le lot d'origine" - de sorte que l'OP est au courant d'avoir des lots différents et une liste différente des plaquettes, mais le Même Wafers. Sa question n'était pas sur la synchronisation supplémentaire de la synchronisation de l'original et de la copie des lots, mais de supprimer les plaquettes sans affecter l'original. Quoi qu'il en soit, la discussion s'éloigne du problème réel.


Je me concentrais plus sur le " est-il possible sans copie profonde? " à laquelle la réponse est non, le lot lot doit être cloné avec la propriété elle-même. Ce que l'OP est vraiment demandé, c'est " puis-je avoir 1 lot objet, dans 2 listes distinctes, quelle référence tranche listes " ce qui n'est pas 't possible.



4
votes

Autant que je puisse le voir, il n'y a pas de manière hors de la boîte pour vous de faire ce que vous voulez. Voici une brève description pourquoi:

La liste (extrême gauche) contient une référence à l'objet lot , qui contient à son tour des références aux deux variables de membre.

Entrez la description de l'image ici

Si vous souhaitez des modifications au LOTNAME et des constituants de la liste WAFERS DISPAGE Comme vous le décrivez, la solution la plus facile consiste à partager une référence au Lot objet entre les listes:

Entrez la description de l'image ici

Vous pouvez maintenant voir pourquoi il est impossible de modifier les éléments de la liste des wafers à l'aide de cette solution - vous ne pouvez pas vous éloigner du fait que vous utilisez la même référence d'objet!

En partageant une référence, vous perdez la capacité de contrôler la manière dont les différences de comportement. Pour atteindre ce que vous voulez, je pense que vous devez faire une copie profonde des instances lot , et vous pouvez ensuite gérer la propagation des modifications à travers une sorte de Observateur modèle.


1 commentaires

Wow merci. Cela rend les choses plus claires pour moi! Donc, lorsque j'appelle "nouvelle liste ()" "Il suffira de faire une nouvelle liste pour la même référence de lot. Ok .. que je dois faire une copie profonde. : /



7
votes

Je pense que je peux voir ce que votre problème est ici. Dans votre COPYLIST Vous clonez efficacement la liste, c'est-à-dire xxx

Toutefois, le point de clé à noter ici est le référence au au au Le lot est toujours identique - si efficacement, vous clonageez et remplacez la propriété wafers sur la liste d'origine.

lorsque vous appelez < Pré> xxx

C'est bien parce que vous manipulez une copie du lot la liste . Toutefois, lorsque vous appelez xxx

, vous modifiez le lot lot instance qui est toujours référencé par les deux listes. Pour résoudre le problème, il vous suffirait de cloner le lot d'objet pour modifier efficacement la référence, c'est-à-dire xxx

En conséquence, vous perdriez la mise à jour automatique. dans les deux listes du lot objet lui-même, mais vous le conserveriez toujours de modifier les objets de la plaquette individuels (car la référence pour eux n'aurait pas changé).

Donc de résumer, ce que vous demandez efficacement est:

Comment puis-je conserver la même référence d'objet tout en ayant une référence de propriété différente?

La réponse à cette question est - vous ne pouvez pas.


0 commentaires

0
votes

Vous devez utiliser deux variables distinctes pour les listes, par exemple. listlota et listlotb . Si vous souhaitez être capable de supprimer une plaquette à partir d'une liste sans le retirer d'une autre, puis ajustez une plaquette de sorte qu'elle reflète dans les deux listes, vous devrait copier les plaquettes d'une liste à l'autre, c'est-à-dire en utilisant un tableau temporaire.

Le code exemple ci-dessous illustre ceci: xxx

listlota et listlotb sont des objets distincts, par exemple ils ont des références différentes, mais la liste des plaquettes individuelles a la même référence. xxx

La ligne ci-dessus changerait la plaquette à l'index 1 dans LISTLOTB, mais cela affecterait également la même plaquette à Listlota (malgré son indice). xxx

ceci supprimerait la plaquette w2 de listlota, mais pas de LISTLOTB. < / p>


0 commentaires