Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Pass many objects of the same class to a method

Discussion in 'Scripting' started by ProperNovice, May 8, 2021.

  1. ProperNovice

    ProperNovice

    Joined:
    Nov 1, 2016
    Posts:
    15
    Hello all,

    I am coming from Java and I have a question about passing many objects of the same class to a method.

    We have a class named Animal and a method that belongs to another class that adds one object of the type.

    Code (CSharp):
    1. public void addAnimal(Animal animal)
    Let's say that I want to pass many objects of the class animal but I don't know the amount each time. I could make the methods to accept a list of animals

    Code (CSharp):
    1. public void addAnimal(List<Animal> list)
    In Java you can do it like this:

    Code (CSharp):
    1. public void addAnimal(Animal... animal)
    Basically using this syntax you can pass as many objects as you like. For example

    Code (CSharp):
    1. addAnimal(Animal a, Animal b, Animal c)
    This is perfectly fine. Practically in Java this animal object referenced in the addAnimal method is an Array type of Animal with as many objects as you pass through.

    Does something like this exist in C#?

    Thank you
     
  2. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,913
    Bunny83 and ProperNovice like this.
  3. ProperNovice

    ProperNovice

    Joined:
    Nov 1, 2016
    Posts:
    15
    Thank you Ninja, much appreciated
     
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    Be aware that when using a params array you always have the overhead of implicitly creating that array whenever you call the method. So the params array is essentially just syntactic sugar. So a call like

    addAnimal(animal1, animal2, animal3);


    will actually result in this code:

    addAnimal(new Animal[]{animal1, animal2, animal3});


    There's not really a neat way to avoid that array allocation. Most methods that provide a params array often have several overloads for small number of parameters and the params version for anything above a certain count.

    Code (CSharp):
    1. public void addAnimal(Animal animal1)
    2. // [ ... ]
    3. public void addAnimal(Animal animal1, Animal animal2)
    4. // [ ... ]
    5. public void addAnimal(Animal animal1, Animal animal2, Animal animal3)
    6. // [ ... ]
    7. public void addAnimal(params Animal[] animals)
    8. // [ ... ]
    9.  
    Of course that requires to implement the code either several times or use clever chaining. In the case of just adding an animal to some kind of internal list, it would be rather trivial.

    Code (CSharp):
    1. public void addAnimal(Animal animal1)
    2. {
    3.     list.Add(animal1);
    4. }
    5. public void addAnimal(Animal animal1, Animal animal2)
    6. {
    7.     list.Add(animal1);
    8.     list.Add(animal2);
    9. }
    10. public void addAnimal(Animal animal1, Animal animal2, Animal animal3)
    11. {
    12.     list.Add(animal1);
    13.     list.Add(animal2);
    14.     list.Add(animal3);
    15. }
    16. public void addAnimal(params Animal[] animals)
    17. {
    18.     list.AddRange(animals);
    19. }
    20.  
    Of course if the logic for adding one animal is more complex, you could simply chain the methods. Something like this:

    Code (CSharp):
    1. public void addAnimal(Animal animal1)
    2. {
    3.     // your adding code
    4. }
    5. public void addAnimal(Animal animal1, Animal animal2)
    6. {
    7.     addAnimal(animal1);
    8.     addAnimal(animal2);
    9. }
    10. public void addAnimal(Animal animal1, Animal animal2, Animal animal3)
    11. {
    12.     addAnimal(animal1);
    13.     addAnimal(animal2);
    14.     addAnimal(animal3);
    15. }
    16. public void addAnimal(params Animal[] animals)
    17. {
    18.     foreach(var animal in animals)
    19.         addAnimal(animal);
    20. }
    21.  
     
    ProperNovice likes this.
  5. ProperNovice

    ProperNovice

    Joined:
    Nov 1, 2016
    Posts:
    15
    Bunny I haven't thought of creating a few overload methods to cover a specific small amount of passing reference objects to avoid the array allocation. This is a very clever and simplistic method to do it.

    In my current program I add 4 at max so I am instantly creating your suggestion. You can even use the other overloaded methods to skip few lines of code.

    Code (CSharp):
    1. public void addAnimal(Animal animal1)
    2. {
    3.     // your adding code
    4. }
    5. public void addAnimal(Animal animal1, Animal animal2)
    6. {
    7.     addAnimal(animal1);
    8.     addAnimal(animal2);
    9. }
    10. public void addAnimal(Animal animal1, Animal animal2, Animal animal3)
    11. {
    12.     addAnimal(animal1, animal2);
    13.     addAnimal(animal3);
    14. }
    15. public void addAnimal(Animal animal1, Animal animal2, Animal animal3, Animal animal4)
    16. {
    17.     addAnimal(animal1, animal2, animal3);
    18.     addAnimal(animal4);
    19. }
    20. public void addAnimal(params Animal[] animals)
    21. {
    22.     foreach(var animal in animals)
    23.         addAnimal(animal);
    24. }
    You provided me an extra layer of thinking proccess.

    Thank you
     
    Kurt-Dekker likes this.
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    Well, doing such deeply nested chains is of course possible, but doesn't really provide any advantages. It's actually the opposite. Every method call has some cpu overhead. So it's slightly better for performance if you have them just calling the method "n" times in a row. In such a small case it really doesn't matter, but it shouldn't become an overly used technique :) Your 4 element version essentially has 7 internal method calls when only 4 are needed.
     
    ProperNovice likes this.
  7. ProperNovice

    ProperNovice

    Joined:
    Nov 1, 2016
    Posts:
    15
    I didn't know the cpu overhead. So it is better just to do it in your original way.

    Thanks again Bunny