2014-02-13 2 views
3

У меня есть несколько классов, для которых требуется множество параметров. Я просто создал пример с двумя параметрами, чтобы продемонстрировать свою проблему.Принять параметры метода из конструктора

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; 
    } 
} 

Если я хочу добавить к моему AnimalZoo у меня есть 2 варианта.

  1. передавать все параметры к AddAnimal Метод
  2. Добавить Animal объект в List

Как я уже сказал, у меня есть много Params и много «Animals».

Возможно ли связать параметры конструктора Animal без добавления их вручную в метод AddAnimal? (См.: -> pseudo code <- в первом кодовом блоке)

Но я хочу, чтобы вызов метода.

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

Спасибо заранее, Jan

Edit: По какой-то причине, я хочу, чтобы предотвратить с помощью одного из следующих способов:

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

Итак, последний вопрос : Возможно ли использовать только параметры конструктора без c & p их в метод?

+0

Ваш подход к параметру [] - это, вероятно, все, что вы можете получить для автоматического проксирования параметров (проверка типа времени выполнения и торговля боксом) ... Читайте на [factory] (http://en.wikipedia.org)/wiki/Abstract_factory_pattern), поскольку это, вероятно, то, что вы пытаетесь достичь ... Или, может быть, t4 (шаблоны для VS для генерации кода ...) –

ответ

5

Нет, вы не можете автоматически проксировать все индивидуальные параметры конструктора. Но вы можете переложить бремя для вызывающего абонента:

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

Или вы можете просто скопировать/вставить подпись/конструктор-вызов вручную в соответствии с вашим «передавать все параметры». Например,

+0

Правильно, thaks. Но я хочу предотвратить создание объектов за пределами «Zoo» -Class. Как я уже сказал, у меня много животных, у которых больше параметров. Нельзя ли передать только параметры generic? Благодаря! – Jan

+1

@ Джан нет, это не так; кроме того, со структурами, как показано, вызывающие могут уже обойти все: 'zoo.Animals.Add (новый Iguanodon());' (где 'Iguanodon: Animal', очевидно) –

+1

+1 вы не можете получить автоматический общий прокси все параметры И проверка времени компиляции ... –

1

Я думаю, что основная идея должна быть чем-то вроде этого:

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()); 
     } 
    } 
} 

Но лучшее, что вы можете сделать этот путь проходит по вашему методу общие объекты, а не конкретные типы, которые по моему мнению, не является хорошим Идея (если вы НЕ НАСТОЯТЕЛЬНО уверены, что у вас есть тип, проверенный ранее)

Другой совет: если у вас есть много свойств, как вы говорите, избегайте реализации конструктора. Я думаю, более управляемым, не имея дело с ним (особенно, если некоторые свойства могут быть нулевыми).

+0

Спасибо. Это было бы возможно, но мне нужно безопасное решение типа. Потому что все параметры необходимы. Кроме того, здесь (здесь называется) Zoo-класс хранит данные. На самом деле в ней нет никакой логики. Во всяком случае: Спасибо за ваш ответ. – Jan

Смежные вопросы