Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adopt method parameters from constructor

I have some classes that require a lot of parameters. I just created an example with two params to demonstrate my problem.

public class Zoo
{
    public List<Animal> Animals { get; set; }

    public Zoo()
    {
        Animals = new List<Animal>();
    }

    // Pass all parameters
    public void AddAnimal(string name, int age)
    {
        Animals.Add(new Animal(name, age));
    }

    // -> pseudo code <- Create the parameter reference automated -> pseudo code <-
    public void AddAnimal(params ...)
    {
        Animals.Add(new Animal(...));
    }
}

public class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Animal(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

If I want to add an Animal to my Zoo I have 2 choices.

  1. Pass all parameters to the AddAnimal Method
  2. Add an Animal object to the List

As I said, I have a lot of params and a lot of "Animals".

Is it possible to reference the parameters of the Animal constructor without adding them manually to the AddAnimal method? (See: -> pseudo code <- in the first code block)

But I want to keep the method call.

Zoo zoo = new Zoo();
zoo.AddAnimal("Tom", 8);

Thanks in advance, Jan

Edit: For some reason, I want to prevent using one of the following methods:

zoo.AddAnimal(new Animal("Ben", 9));
zoo.AddAnimal(new Animal { "Ben", 9 }); // With empty constructor...

So, the final question is: Is it possible to just use only the constructor parameters without c&p them into the method?

like image 367
Jan Avatar asked Jul 19 '26 12:07

Jan


2 Answers

No, you can't proxy all of the individual constructor parameters automatically. But you can shift the burden to the caller:

public void Add(Animal animal)
{
    if(animal == null) throw new ArgumentNullException("animal");
    Animals.Add(animal);
}
...
zoo.Add(new Animal("Fred", 27));

Or you can just copy/paste the signature/constructor-call manually as per your "Pass all parameters" example.

like image 132
Marc Gravell Avatar answered Jul 22 '26 01:07

Marc Gravell


I think the basic idea should be something like this:

public class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override string ToString()
    {
        return "[" + Name + ", " + Age + "]";
    }
}

public class Zoo
{
    public List<Animal> Animals { get; set; }

    public Zoo()
    {
        Animals = new List<Animal>();
    }

    // Pass all parameters
    public void AddAnimal(string name, int age)
    {
        Animal animal = new Animal
        {
            Name = name,
            Age = age
        };

        Animals.Add(animal);
    }

    // -> pseudo code <- Create the parameter reference automated -> pseudo code <-
    public void AddAnimal(params object[] animalProperties)
    {
        Animal animal = new Animal
        {
            Name = animalProperties[0] as string,
            Age = (animalProperties[1] as int?).Value
        };

        Animals.Add(animal);
    }
}

public class Example
{
    public void Run()
    {
        Zoo zoo = new Zoo();
        zoo.AddAnimal("Tom", 8);

        foreach (Animal a in zoo.Animals)
        {
            Console.WriteLine(a.ToString());
        }
    }
}

But the best you can do this way is passing to your method generic objects and not specific types which in my opinion isn't a good idea (unless you are REALLY sure that you have type checked them before)

Another advice: if you have lots of properties as you say avoid the implementation of the constructor. I think is more manageable not having to deal with it (especially if some properties can be null).

like image 35
Terenzio Berni Avatar answered Jul 22 '26 01:07

Terenzio Berni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!