Jump to content
Unity Insider Forum
Sign in to follow this  
Strooja0108

Liste in eine Liste kopieren

Recommended Posts

Hallo Leute,

ich habe kleines Problem woran ich gerade verzweifel und hatte gehofft Ihr könnt mir vielleicht helfen.

Stellt euch vor ihr geht in ein Restaurant und bekommt die Karte . Auf dieser Karte kreuzt ihr dann an was ihr haben möchtet und gebt die Karte dann zurück an den Kellner als Bestellung.Sowas würde ich gerne umsetzen

Dafür habe ich eine Liste mit attributen für jedes gericht :

public class FoodDrinkList : MonoBehaviour
{
    [System.Serializable]
    public class Fooddetails
    {
    public string foodname;
    public Sprite picture;
    public int id;    
    public int price;
    public int happiness;
    public int energy;
    public int hungry;
    public int amount;
    public int slots;
    public int unlocked;
    }
    public List<Fooddetails> FoodList;
}

 

Diese liste "FoodList" verändere ich dann in dem ich sage wie viel ich von jedem Gericht haben möchte und dann möchte ich per Button klick diese FoodList in eine andere Foodlist schreiben

 public FoodDrinkList foodDrinkList;

[System.Serializable]
    public class Delivery
    {
        public FoodDrinkList FoodList;
        public int deliveryday;
        public int deliveryhour;
        public int readytopickup;
    }

 

public void BuyButton()
    {
        Delivery newDelivery = new Delivery();

         List<FoodDrinkList> clonedList = new List<FoodDrinkList>(foodDrinkList);   //Hier habe ich versucht die Liste zu klonen.Ich habe aber garkeine Idee wie ich die liste kopieren kann

        newDelivery.FoodList.FoodList.Add(clonedList);

        newDelivery.deliveryhour = DataTimescript.hourtimer + 3;    

        DeliveryList.Add(newDelivery);
     
    }

 

Es funktioniert alles bis auf den Teil mit dem kopieren der Foodlist in die neue Delivery.Foodlist.Foodlist

 

Hat da jemandeine Idee?

 

Share this post


Link to post
Share on other sites
List<FoodDrinkList> clonedList = new List<FoodDrinkList>(foodDrinkList); 

Das ist schon, wie man eine neue Liste erstellt, die dieselben Elemente beinhaltet. Ist aber eine "Flat Copy", das heißt: Wenn deine Elemente Referenzen sind, dann werden halt die Referenzne kopiert, nicht aber die Objekte, die da referenziert werden. Es klingt, als wolltest du eine "Deep Copy", bei der die referenzierten Objekte auch kopiert werden?

Du könntest sonst überlegen, ein Struct statt einer Klasse zu verwenden, die haben keine Referenzsemantik. Wenn du eine Liste von Structs hast, dann sind die Elemente entsprechend keine Referenzen, sondern Objekte selbst.

Um Verwirrung und Problemen vorzubeugen, solltest du außerdem überlegen, deine Datenhalter in feste Informationen über Gerichte und Bestellungen aufzuteilen. Wenn ich mich nicht irre, ist die Eigenschaft "amount" in "Fooddetails" dazu da, um die Menge eines Gerichts in einer Liste darzustellen. Damit steht diese Eigenschaft im Kontrast zu den anderen Feldern, die fixe Informationen über das Gericht beinhalten. Mal als Beispiel, wie das anders aussehen könnte:

[System.Serializable]
public class FoodDetails
{
  public string name;
  public Sprite picture;
  piblic int happiness;
}

Wenn du Propertys benutzt, kannst du diese Informationen auch readonly machen, sodass da kein™ Code geschrieben werden kann, der da in den Werten rumfummelt. Falls du das probieren willst, sag bescheid, aber ich lasse das der Einfachheit halber gerade Mal weg.

Dann baust du noch ein Struct für einen Bestellpunkt:

[System.Serializable]
public struct OrderItem
{
  public FoodDetails food;
  public int amount;
}

Und dann machst du davon eine Liste. Da du dann eine Liste von Struct-Objekten hast, kannst du OrderItems beliebig umherschieben und kopieren. Das "FoodDetails"-Objekt, das da referenziert wird, wird nicht mitkopiert, da "FoodDetails" eine Klasse ist. Ist ja aber in Ordnung, weil in diesen Objekten nichts mehr drinsteht, das wir ändern würden. Die Daten in diesen Objekten sind also statisch, ändern sich nicht und gelten für alle gleich. Diese Daten also mehrfach zu haben wäre Platzverschwendung.

  • Like 1

Share this post


Link to post
Share on other sites

Hey vielen dank für die ausführliche Antwort. Du hast recht das ich eine Deep copy brauche.Das beispiel mit dem restaurant ist nicht genau das was ich machen möchte.Es sollte nur darstellen was ich ungefähr vor habe. Du hast auch recht das es Sinn machen würde, den größten Teil read only zu machen ,denn nur amount ist ein wert der sich verändert.

 

Ich habe aber immer noch nicht so ganz verstanden wie ich FoodList in DeliveryList erstelle.Das mit dem Copy erstellen oder per Hand die Liste füllen erzeugt immer Fehler das das Object nicht da ist zum Beispiel.  Um nochmal genauer zu erklären was ich machen möchte.Ich habe einmal diese FoodList wo ich die Mengen der Gerichte verändere. Diese Liste möchte ich dann in DeliveryList schreiben und zusätzlich angeben an welchem Tag die Delivery kommt. Wenn dieser Tag dann erreicht ist wird die DeliveryList  in eine neue Liste "FridgeList" addiert. Im Prinzip so wie wenn man etwas Online bestellt ,wartet bis es da ist und es dann in den Kühlschrank legt.

 

 

Ih habe das jetzt mal probiert, an der Stelle wo ich vorher die clonedList erstellt habe:

 

for (int i = 0; i < FoodDrinkList.FoodList.Count; i++)
        {
            newDelivery.FoodList.FoodList.Add(FoodDrinkList.FoodList);
        }

 

 

Ich bekomme dann aber diesen Fehler:

NullReferenceException: Object reference not set to an instance of an object
BuyFoodScript.BuyButton () (at Assets/Scripts/BuyFoodScript.cs:151)

 

Es bezieht sich auf die Zeile in dem for loop

 

 

Ich habe jetzt auch das hier nochmal ausprobiert aber das klappt auch nicht.

 


        Delivery newDelivery = new Delivery();

        FoodDrinkList.Fooddetails newFood = new FoodDrinkList.Fooddetails();

        for (int i = 0; i < FoodDrinkLists.FoodList.Count; i++)
        {
            newFood.foodname = FoodDrinkLists.FoodList.foodname;
            newFood.price = FoodDrinkLists.FoodList.price;
            newFood.id   = FoodDrinkLists.FoodList.id;
            newFood.happiness = FoodDrinkLists.FoodList.happiness;
            newFood.hungry = FoodDrinkLists.FoodList.hungry;
            newFood.picture = FoodDrinkLists.FoodList.picture;
            newFood.slots = FoodDrinkLists.FoodList.slots;
            newFood.unlocked = FoodDrinkLists.FoodList.unlocked;
            newFood.energy = FoodDrinkLists.FoodList.energy;
            newFood.amount = FoodDrinkLists.FoodList.amount;

            newDelivery.FoodList.FoodList.Add(newFood);
        }

  Es kommt der gleiche Fehler.Ich denke das Problem ist das ich verschiedene Variablen gleichzeitig adden möchte. Weiß jemand wie man eine Klasse mit unterschiedlichen Werten zu einer Liste hinzufügt??

 

Share this post


Link to post
Share on other sites
Am 26.3.2020 um 18:36 schrieb Strooja0108:

Du hast recht das ich eine Deep copy brauche.

Ganz ehrlich, da bin ich mir nichtmal so sicher. Wenn du deine Daten aufteilst in Klassen mit unveränderlichem Inhalt (die man nicht kopieren braucht, weil es aufgrund der Unveränderlichkeit okay ist, wenn einfach alle dasselbe Objekt referenzieren) und Structs für die temporären Daten einer Bestellung (wo man keine Deep Copy braucht, weil bei Listen von Structs die Struct-Objekte, also die Daten, direkt in der Liste stehen anstatt referenziert zu werden), dann solltest du ohne Deep Copy klar kommen.

Verwirf mal den aktuellen Ansatz und versuche, dir deine Datenstrukturen entsprechend aufzubauen.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...